题目集1~3总结
一、前言
作业一:主要学会了Java程序中的输入和输出,这是第一次写Java程序,对基本的输入和输出并不了解,第一次作业基本都是采用简单的输入和输出的形式,没有太难的逻辑推理题,都是一些简单的逻辑,第一次的作业难度不大,题量比较多,只是对于java的程序结构有了一个初步的了解。
作业二:主要学会了一些逻辑的推理以及一些函数的运用。作业二中题目相较于作业一的难度大了很多,逻辑上的推理难度更大,并且用到了一些自学的函数。题目量相对于题目一少了一些,知识点还是一些基本的逻辑推理,只是需要考虑的更加全面,比如求下一天时,需要考虑到是不是闰年的二月,下一天会不会跨年等等之类的问题
。
作业三:第三次作业主要涉及到了类的创建。需要在类里定义属性,创建一些简单的方法,类似于构造函数但是也有区别。作业题量不多,但由于是首次接触,难度感觉还是比较大的,需要有一定的了解才能将题目做出来。
二、设计与分析
针对一些难度较大的题目,在这里做出相应的分析
(1)题目集一7-8:判断三角形类型
题目要求:在一行中输入三角形的三条边的值(实型数),可以用一个或多个空格或回车分隔,其中三条边的取值范围均为[1,200]
题目分析:本题要求输入三个数,首先判断是否能构成一个三角形,再判断能否构成特殊的三角形,由已学知识可知道,两条短边相加要大于最长的边,而数据的输入是无法控制的,所以要先对输入的数据进行一个排序,对之后是否为三角形的判断以及是否构成特殊三角形的判断都更加的简单。先进行排序,再根据各种三角形的定义进行判断。
排序代码:
double a = scanner.nextDouble();
double b = scanner.nextDouble();
double c = scanner.nextDouble();
double temp = a;
if (a > b) {
temp = b;
b = a;
a = temp;
}
if (b > c) {
temp = c;
c = b;
b = temp;
}
将三位数字的大小依次排好再进行计算
三角形类型的判断:
这里需要注意到一些细节,比如等边三角形又符合等腰三角形的判断,这时候不能重复判断,需要判断第三条边不相等,判断条件如下
if (a == b && b == c)
System.out.println("Equilateral triangle");
if (a == b && a * a + b * b != c * c && b != c)
System.out.println("Isosceles triangle");
这里保证a^2+b^2!=c^2是令他不符合等腰直角三角形的条件,等腰三角形和等腰直角三角形也有相同的条件,为了避免重复的判断,需要进行一个判断,这些细节是很容易出错的,需要谨慎一点。最后,直角三角形的判断与等腰直角三角形的判断也是需要一点细节的判断的,要保证两条短边不相等,才输出是直角三角形。一
(2)题目集一7-6:使用一维数组求平均值
题目分析:本题需要用到一位数组,对题目进行分析,该题需要进行一位数组的构建,一维数组的赋值,以及计算平均值。Java中数组的构造与c语言的数组并不一样代码如下:
double[] a = new double[5];
这样就创建了一个长度为5的数组
数组的赋值以及计算通过一个循环结构来进行,代码如下
for (i = 0; i < 5; i++) {
a[i] = scanner.nextDouble();
sum = sum + a[i];
}
最后计算平均值并且输出即可。
(3)题目集二7-1:IP地址的转换
题目分析:本题需要输入一个32位数的字符串,且必须为二进制,若输出错误,则输出错误提示。若输入正确,则将其变成十进制数输出,并且以八位数为一个单位进行输出。
首先输入一个字符串,将其变为一个字符数组,为之后计算更方便,代码如下:
Scanner scanner=new Scanner(System.in);
String str=scanner.nextLine();
char[] s=str.toCharArray();
接下来判断输入是否正确,代码如下:
if(s.length!=32)
{
System.out.println("Wrong Format");
System.exit(0);
}
for(i=0;i<s.length;i++)
{
if(s[i]!='0'&&s[i]!='1')
{
System.out.println("Wrong Format");
System.exit(0);
}
}
若输入正确的话,则进行计算,通过一个嵌套循环将字符串分割进行计算,代码如下:
for(i=0;i<4;i++) {
for (j=7; j>=0; j--) {
if (s[j + 8 * i] == '1')
d[i] += Math.pow(2,7-j);
}
}
用一个数组储存数值更方便输出。
(4)题目集二7-4:求下一天
题目要求:输入年月日的值(均为整型数),输出该日期的下一天。 其中:年份的合法取值范围为[1820,2020] ,月份合法取值范围为[1,12] ,日期合法取值范围为[1,31] 。
题目分析:本题需要用到构造判断是否是闰年的函数,判断输入日期是否合法的函数,求输入日期下一天的函数。
本题难点:首先需要判断月份的输入,将有相同天数的月份归在一起更方便进行判断,但12月应该拿出来单独判断,应该需要判断是否跨年。二月份的判断也应该单独拿出来,首先判断是否为闰年,再判断是否为二月份的最后一天,其他月份直接求即可,只需注意是否为当前月份的最后一天。
首先构造判断判断是否为闰年的函数,代码如下:
public static boolean isLeapYear(int year) {
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)
return true;
else
return false;
}
接下来构造判断输入日期是否正确的函数,代码如下:
public static boolean checkInputValidity(int year,int month,int day){
if (year < 1820 || year > 2020 || month < 1 || month > 12 || day < 1 || day > 31 )
return false;
else if(isLeapYear(year)==false&&month==2&&day==29)
return false;
else
return true;
}
这里需要注意的是当年份为平年时,二月份输入29号是需要报错的
接下来构造求下一天的函数,首先将12月份和二月份单独拿出来判断,代码如下:
if (day==31&&month==12)
System.out.println("Next date is:"+(year+1)+"-1-"+"1");
else
System.out.println("Next date is:"+year+"-"+(month+1)+"-"+"1");
if(month==2){
if(isLeapYear(year)==true){
if(day==29)
System.out.println("Next date is:"+year+"-"+(month+1)+"-"+"1");
else
System.out.println("Next date is:"+year+"-"+month+"-"+(day+1));
}
else
{
if(day==28)
System.out.println("Next date is:"+year+"-"+(month+1)+"-"+"1");
else
System.out.println("Next date is:"+year+"-"+month+"-"+(day+1));
}
}
其他月份的类似,不过多赘述了。
在主函数中将几个子函数调用,代码如下:
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int year = scanner.nextInt();
int month = scanner.nextInt();
int day = scanner.nextInt();
//判断数值是否合法
if (year < 1820 || year > 2020 || month < 1 || month > 12 || day < 1 || day > 31) {
System.out.println("Wrong Format");
System.exit(0);
}
boolean a = isLeapYear(year);//调用判断闰年的函数
if(a==false){
if(month==2&&day==29)
{
System.out.println("Wrong Format");
System.exit(0);
}
}
boolean check=checkInputValidity(year,month,day);//调用判断输入数据是否正确的函数
nextDate(year,month,day);//调用求下一天的函数
}
(5)题目集二7-5:求前N天
题目要求:输入年月日的值(均为整型数),同时输入一个取值范围在[-10,10] 之间的整型数n,输出该日期的前n天(当n > 0时)、该日期的后n天(当n<0时)。
其中年份取值范围为 [1820,2020] ,月份取值范围为[1,12] ,日期取值范围为[1,31] 。
题目分析:本题的主要难度是有很多种情况需要考虑,很难考虑周全,输入的N是正还是负,考虑会不会跨月份,考虑会不会跨年,二月份还需单独拿出来考虑,首先考虑是不是闰年,再判断会不会跨月份。
该题与7-4也有相似之处,首先判断日期输入是否错误,可参照7-4的判断代码。
将月份相同的天数放在一起判断,当N大于0时,需要将1,3,8月单独拿出来判断,月份为1时需要判断是不是会跨年,代码如下:
if (n > 0) {
if (day - n >= 1)
System.out.println(n + " days ago is:" + year + "-" + month + "-" + (day - n));
if (day - n < 1) {
if (month == 3)
System.out.println(n + " days ago is:" + year + "-" + (month - 1) + "-" + (28 - n + day));
else if (month == 1)
System.out.println(n + " days ago is:" + (year - 1) + "-12-" + (31 - n + day));
else if(month==8)
System.out.println(n + " days ago is:" + year + "-" + (month - 1) + "-" + (31 - n + day));
else
System.out.println(n + " days ago is:" + year + "-" + (month - 1) + "-" + (30 - n + day));
}
}
这里将平年时所有天数为31天的月份的前n天输出的代码
闰年的二月份只需要多需进行一个判断,这里就不进行赘述了
当n<0时,需要对12月和2月单独拿出来判断即可,和上面代码类似。
最后将结果输出。
(6)题目集三7-2:定义日期类
题目要求:定义一个类Date,包含三个私有属性年(year)、月(month)、日(day),均为整型数,其中:年份的合法取值范围为[1900,2000] ,月份合法取值范围为[1,12] ,日期合法取值范围为[1,31] 。
题目分析:该题首先需要定义一个日期类,里面包含年月日三个属性以及一个包含每个月份天数的一维数组。在里面定义获取对象年月日的方法,还有判断输入是否错误以及判断是否是闰年的办法,最后在构造一个输出下一个日期的方法。
判断输入是否错误以及判断是否为闰年可参考上述代码
输出下一天方法可参考上一题输出下一天的代码,无需过多变动。代码如下:
Void getNextDate(){
if (a.month == 1 || a.month == 3 || a.month == 7 || a.month == 5 || a.month == 8 || a.month == 10 || a.month == 12){
if(a.day<=30)
System.out.println("Next day is:"+a.year+"-"+a.month+"-"+(a.day+1));
else if (a.day==31&&a.month==12)
System.out.println("Next day is:"+(a.year+1)+"-1-"+"1");
else
System.out.println("Next day is:"+a.year+"-"+(a.month+1)+"-"+"1");
}
if(a.month==2){
if(isLeapYear(a.year)==true){
if(a.day==29)
System.out.println("Next day is:"+a.year+"-"+(a.month+1)+"-"+"1");
else
System.out.println("Next day is:"+a.year+"-"+a.month+"-"+(a.day+1));
}
else
{
if(a.day==28)
System.out.println("Next day is:"+a.year+"-"+(a.month+1)+"-"+"1");
else
System.out.println("Next day is:"+a.year+"-"+a.month+"-"+(a.day+1));
}
}
if(a.month==4||a.month==6||a.month==9||a.month==11)
{
if(a.day<=29)
System.out.println("Next day is:"+a.year+"-"+a.month+"-"+(a.day+1));
else
System.out.println("Next day is:"+a.year+"-"+(a.month+1)+"-"+"1");
}
}
}
主函数中调用类中的各种方法,将其输出即可。
(7)题目集三7-3:一元多项式求导
题目要求:编写程序性,实现对简单多项式的导函数进行求解。
题目分析:首先进行一个字符串的输入,如何将字符串中的空格全部删除方便之后计算的进行
代码如下:
Scanner input = new Scanner(System.in);
String str=input.nextLine();
str=str.replace(" ", "");
判断输入是否错误,输出错误提示,代码如下:
for(i=0;i<str.length();i++)
{
if(s[i]=='*'){
if(s[i-1]=='0'){
System.out.println("Wrong Format");
System.exit(0);
}
}
if(s[i]=='^'){
if(s[i+1]=='0'){
System.out.println("Wrong Format");
System.exit(0);
}
}
}
求导代码:
for(i=0;i<str.length();i++){
if(s[i]=='*'){
s1=str.substring(a,i-1);
temp1=Integer.parseInt(s1);
if(s[i+1]=='x'&&s[i+2]=='^')
for(j=i+2;s[j]!='*';j++);
for(;s[j]!='+'||j!='-';j--);
s2=str.substring(i+3,j-1);
temp2=Integer.parseInt(s2);
temp1=temp1*temp2;
temp2--;
}
}
最后将其输出。
三、踩坑心得
第一次作业总体情况还好,逻辑较为简单,并没有太多问题。第二次作业IP地址的转化一开始并没有找到合适的方法,想一个一个去对比分析,发现根本行不通,无法控制乘的位数。通过两个循环控制结构,发现很快就能解决。其他题目都是较为简单的逻辑推理,只要细心一点都能做出来。第三次作业相对于一二次作业更难了。第三次作业接触到类的设计,有些东西刚开始接触,碰到了不少的错误,经过细致的学习都能解决。但7-3花了很多时间去写,最后还是有测试点无法通过,还是逻辑思考上出现了问题,最终也无法解决。
四、改进建议
对于第一次作业,代码已经比较简洁了,无需过多的继续改进。第二次作业设计到很多逻辑上的问题。比如求下一天时,我将是不是闰年判断了一次,然后在这个总体上进行后面代码的书写,其实完全可以将闰年的判断放到二月份求下一天去做。还有输入日期错误的判断,完全可以放在一起去判断,比如平年二月二十九日的判断和输入日期错误的判断,放在一起即可,没必要分开来判断,导致很多代码重复。
五、总结
通过这三次作业,让我对Java程序有了一个初步的了解,并且了解到了自身编程能力的不足,需要更多的学习以及实践来改进自己的编程能力。对一些写的好的代码可以仔细认真的阅读,学习这种方法,从而提高自己的编程水平。