前三次作业总结
1.前言
(1)第一次题目集共有8道题目,难度较为简单,知识点为JAVA的一些编程基础知识点,如输入输出,选择,循环,一维数组等。
(2)第二次题目集共有5道题目,难度较第一次题目集有所提升,不过总体来说依旧较为简单。题目7-1有关知识点为从字符串中提取一个字符串,用到了charAt的方法,阿斯克码值的有关知识。题目7-2有关知识点为合并两个字符串,用到了arraycopy的方法。题目7-3,7-4,7-5的知识点均是对日期的判断和处理,还有方法的使用,构造多个方法再进行调用完成其功能。
(3)第三次题目集共有3道题目,难度较第一次题目集和第二次题目集有显著提升,个人认为第三道题目难度较高,第三次题目集开始,我们开始逐步进入面向对象的程序设计,7-1.7-2两道题主要新加入的知识点是创建新的类,在新的类中创建属性,以及如何在其他类中创建对象和调用其他类的方法,含参数不含参数的构造方法,getset的构造方法的使用,属性私有性的知识点等。题目7-3的知识点为对字符串的判断以及处理等,其中用到了正则表达式的相关知识点,大数的知识点等。
2.设计与分析
(1)第一次习题集7-8判断三角形类型
输入三角形三条边,判断该三角形为什么类型的三角形。
输入格式:
在一行中输入三角形的三条边的值(实型数),可以用一个或多个空格或回车分隔,其中三条边的取值范围均为[1,200]。
输出格式:
(1)如果输入数据非法,则输出“Wrong Format”; (2)如果输入数据合法,但三条边不能构成三角形,则输出“Not a triangle”; (3)如果输入数据合法且能够成等边三角形,则输出“Equilateral triangle”; (3)如果输入数据合法且能够成等腰直角三角形,则输出“Isosceles right-angled triangle”; (5)如果输入数据合法且能够成等腰三角形,则输出“Isosceles triangle”; (6)如果输入数据合法且能够成直角三角形,则输出“Right-angled triangle”; (7)如果输入数据合法且能够成一般三角形,则输出“General triangle”。
源代码:
1 import java.util.Scanner; 2 3 public class Main { 4 5 public static void main(String[] args) { 6 Scanner input = new Scanner(System.in); 7 double x=input.nextDouble(); 8 double y=input.nextDouble(); 9 double z=input.nextDouble(); 10 if((x>200||x<1)||(y>200||y<1)||(z>200||z<1)) 11 System.out.print("Wrong Format"); 12 else if((x+y)<=z||(x+z)<=y||(y+z)<=x) 13 System.out.print("Not a triangle"); 14 else if(x==y&&y==z) 15 System.out.print("Equilateral triangle"); 16 else if((x==y&&x*x+y*y-z*z<0.00001)||(x==z&&x*x+z*z-y*y<0.00001)||(y==z&&y*y+z*z-x*x<0.00001)) 17 System.out.print("Isosceles right-angled triangle"); 18 else if(x==y||x==z||y==z) 19 System.out.print("Isosceles triangle"); 20 else if((x*x+y*y-z*z<0.00001)||(x*x+z*z-y*y<0.00001)||(y*y+z*z-x*x<0.00001)) 21 System.out.print("Right-angled triangle"); 22 else 23 System.out.print("General triangle"); 24 25 26 27 } 28 29 }


从图中可以看到,本题目只有31行代码,题目本身也较为简单,使用if else语句,但是由于我自己用了大量的if else语句,导致简简单单的31行代码却拥有着19的复杂度。
(2)题目集二7-4求下一天
输入年月日的值(均为整型数),输出该日期的下一天。 其中:年份的合法取值范围为[1820,2020] ,月份合法取值范围为[1,12] ,日期合法取值范围为[1,31] 。 注意:不允许使用Java中和日期相关的类和方法。
要求:Main类中必须含有如下方法,签名如下:public static void main(String[] args);//主方法
public static boolean isLeapYear(int year) ;//判断year是否为闰年,返回boolean类型
public static boolean checkInputValidity(int year,int month,int day);//判断输入日期是否合法,返回布尔值
public static void nextDate(int year,int month,int day) ; //求输入日期的下一天
输入格式:
在一行内输入年月日的值,均为整型数,可以用一到多个空格或回车分隔。
输出格式:
- 当输入数据非法及输入日期不存在时,输出“Wrong Format”;
- 当输入日期合法,输出下一天,格式如下:Next date is:年-月-日
源代码:
1 import java.util.Scanner; 2 3 public class Main { 4 5 public static void main(String[] args) { 6 Scanner input = new Scanner(System.in); 7 int Y = input.nextInt(); 8 int M = input.nextInt(); 9 int D = input.nextInt(); 10 if(checkInputValidity(Y,M,D)) 11 nextDate(Y,M,D); 12 else 13 System.out.print("Wrong Format"); 14 15 16 17 } 18 public static boolean isLeapYear(int year) { 19 if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) 20 return true; 21 else 22 return false; 23 } 24 25 public static boolean checkInputValidity(int year,int month,int day) { 26 if (year >= 1820 && year <= 2020 && month >= 1 && month <= 12 && day >= 1 && day <= 31) { 27 if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) { 28 if (day > 31) 29 return false; 30 else 31 return true; 32 } 33 if (month == 2) { 34 if (isLeapYear(year)) { 35 if (day > 29) 36 return false; 37 else 38 return true; 39 } 40 else { 41 if (day > 28) 42 return false; 43 else 44 return true; 45 } 46 } 47 if (month == 4 || month == 6 || month == 9 || month == 11) { 48 if (day > 30) 49 return false; 50 else 51 return true; 52 } 53 } 54 return false; 55 } 56 public static void nextDate(int year,int month,int day) { 57 if(month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10) { 58 if(day<31) { 59 day = day+1; 60 System.out.print("Next date is:"+year+"-"+month+"-"+day); 61 } 62 else { 63 day = 1; 64 month = month + 1; 65 System.out.print("Next date is:"+year+"-"+month+"-"+day); 66 System.exit(0); 67 } 68 } 69 if(month == 4 || month == 6 || month == 9 || month == 11) { 70 if(day < 30) { 71 day = day+1; 72 System.out.print("Next date is:"+year+"-"+month+"-"+day); 73 } 74 else { 75 day = 1; 76 month = month + 1; 77 System.out.print("Next date is:"+year+"-"+month+"-"+day); 78 } 79 80 } 81 if(month == 12) { 82 if(day < 31) { 83 day = day+1; 84 System.out.print("Next date is:"+year+"-"+month+"-"+day); 85 } 86 else { 87 day = 1; 88 month = 1; 89 year = year + 1; 90 System.out.print("Next date is:"+year+"-"+month+"-"+day); 91 } 92 } 93 if(month == 2) { 94 if(isLeapYear(year)) { 95 if(day < 29) { 96 day = day+1; 97 System.out.print("Next date is:"+year+"-"+month+"-"+day); 98 } 99 else { 100 day = 1; 101 month = month + 1; 102 System.out.print("Next date is:"+year+"-"+month+"-"+day); 103 } 104 } 105 else { 106 if(day < 28) { 107 day = day+1; 108 System.out.print("Next date is:"+year+"-"+month+"-"+day); 109 } 110 else { 111 day = 1; 112 month = month + 1; 113 System.out.print("Next date is:"+year+"-"+month+"-"+day); 114 } 115 } 116 } 117 } 118 }


(3)题目集二7-5求前n天
输入年月日的值(均为整型数),同时输入一个取值范围在[-10,10] 之间的整型数n,输出该日期的前n天(当n > 0时)、该日期的后n天(当n<0时)。
其中年份取值范围为 [1820,2020] ,月份取值范围为[1,12] ,日期取值范围为[1,31] 。
注意:不允许使用Java中任何与日期有关的类或方法。
输入格式:
在一行中输入年月日的值以及n的值,可以用一个或多个空格或回车分隔。
输出格式:
- 当输入的年、月、日以及n的值非法时,输出“Wrong Format”;
- 当输入数据合法时,输出“n days ago is:年-月-日”
源代码:
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); int Y = input.nextInt(); int M = input.nextInt(); int D = input.nextInt(); int n = input.nextInt(); if(n >=-10&&n <=10) { if(checkInputValidity(Y,M,D)) jsDate(Y,M,D,n); else System.out.print("Wrong Format"); } else System.out.print("Wrong Format"); } 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) { if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) { if (day > 31) return false; else return true; } if (month == 2) { if (isLeapYear(year)) { if (day > 29) return false; else return true; } else { if (day > 28) return false; else return true; } } if (month == 4 || month == 6 || month == 9 || month == 11) { if (day > 30) return false; else return true; } } return false; } public static void jsDate(int year,int month,int day,int n) { if( month == 5 || month == 7 || month == 8 || month == 10) { if(n <= 0 ) { if(day + n < 31) { day = day + n; System.out.print(n+" days ago is:"+year+"-"+month+"-"+day); System.exit(0); } else { day = day + n - 31; month = month + 1; System.out.print(n+" days ago is:"+year+"-"+month+"-"+day); System.exit(0); } } else { if(day - n > 0) { day = day - n; System.out.print(n+" days ago is:"+year+"-"+month+"-"+day); System.exit(0); } else { day = 31 + (day - n); month = month - 1; System.out.print(n+" days ago is:"+year+"-"+month+"-"+day); System.exit(0); } } } if(month == 4 || month == 6 || month == 9 || month == 11) { if(n <= 0) { if(day + n < 30) { day = day + n; System.out.print(n+" days ago is:"+year+"-"+month+"-"+day); System.exit(0); } else { day = day + n - 30; month = month + 1; System.out.print(n+" days ago is:"+year+"-"+month+"-"+day); System.exit(0); } } else { if(day - n > 0) { day = day - n; System.out.print(n+" days ago is:"+year+"-"+month+"-"+day); System.exit(0); } else { day = 31 + (day - n); month = month - 1; System.out.print(n+" days ago is:"+year+"-"+month+"-"+day); System.exit(0); } } } if(month == 12) { if(n <= 0) { if(day - n < 31) { day = day-n; System.out.print(n+" days ago is:"+year+"-"+month+"-"+day); System.exit(0); } else { day = day - n -31; month = 1; year = year + 1; System.out.print(n+" days ago is:"+year+"-"+month+"-"+day); System.exit(0); } } else { if(day - n > 0) { day = day - n; System.out.print(n+" days ago is:"+year+"-"+month+"-"+day); System.exit(0); } else { day = 30 + (day - n); month = month - 1; System.out.print(n+" days ago is:"+year+"-"+month+"-"+day); System.exit(0); } } } if(month == 1) { if(n >= 0) { if(day - n > 0) { day = day + n; System.out.print(n+" days ago is:"+year+"-"+month+"-"+day); System.exit(0); } else { day = day -n +31; month = 12; year = year -1; System.out.print(n+" days ago is:"+year+"-"+month+"-"+day); System.exit(0); } } else { if(day - n > 31) { day = day - n; System.out.print(n+" days ago is:"+year+"-"+month+"-"+day); System.exit(0); } else { day = 31 + (day - n); month = 2; } } } if(month == 2) { if(n >= 0) { if(day - n > 0) { day = day+1; System.out.print(n+" days ago is:"+year+"-"+month+"-"+day); System.exit(0); } else { day = day - n +31; month = month - 1; System.out.print(n+" days ago is:"+year+"-"+month+"-"+day); System.exit(0); } } else { if(day - n < 31) { day =day - n; System.out.print(n+" days ago is:"+year+"-"+month+"-"+day); System.exit(0); } else { if(isLeapYear(year)) day = day - n-29; else day = day - n-28; month = month + 1; System.out.print(n+" days ago is:"+year+"-"+month+"-"+day); System.exit(0); } } } if(month == 3) { if(n >= 0) { if(day - n > 0) { day = day - n; System.out.print(n+" days ago is:"+year+"-"+month+"-"+day); System.exit(0); } else { if(isLeapYear(year)) day = day - n + 29; else day = day - n + 28; month = 2; System.out.print(n+" days ago is:"+year+"-"+month+"-"+day); System.exit(0); } } else { if(day - n < 31 ) { day = day -n; System.out.print(n+" days ago is:"+year+"-"+month+"-"+day); System.exit(0); } else { day = day - n -31; month = month + 1; System.out.print(n+" days ago is:"+year+"-"+month+"-"+day); System.exit(0); } } } } }


对于第二次实验7-4,7-5,两道题都是求日期类的题目,两道题核心算法十分地相似,7-5像是7-4的升级版,我根据年份不用,可能是闰年可能是平年,月份不同。每个月的天数不同,分成了好多好多种情况,然后再一一计算,这又导致我使用了大量的if-else语句,通过if和else来分情况,而且判断是否合法也用if-else,这就导致了圈复杂度特别的高,代码行数也很长7-4的圈复杂度达到了29,而7-5的圈复杂度更是达到了惊人的53,确实代码过于复杂,这是我以后需要思考需要改进的一个重要的点,应该多思考一下如何把复杂度降低,记得老师上课讲过用switch比用if-else复杂度会降低很多,还有用string的方法比switch的方法更加简单,圈复杂度会更低。这两道题主要想让我们学习的是方法的构造和调用,把一个程序的多个步骤,分成多个方法,在调用每一个方法完成整体的功能,我们在7-4,7-5这两道题中就应该学会Java里方法的使用。
(4)题目集三7-2定义日期类
定义一个类Date,包含三个私有属性年(year)、月(month)、日(day),均为整型数,其中:年份的合法取值范围为[1900,2000] ,月份合法取值范围为[1,12] ,日期合法取值范围为[1,31] 。 注意:不允许使用Java中和日期相关的类和方法,否则按0分处理。
要求:Date类结构如下图所示:

输入格式:
在一行内输入年月日的值,均为整型数,可以用一到多个空格或回车分隔。
输出格式:
- 当输入数据非法及输入日期不存在时,输出“Date Format is Wrong”;
- 当输入日期合法,输出下一天,格式如下:Next day is:年-月-日
源代码:
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); int year = input.nextInt(); int month = input.nextInt(); int day = input.nextInt(); Date date = new Date(year,month,day); date.getNextDay(); } } class Date { private int year; private int month; private int day; int [] mon_maxnum = new int[] {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; public Date() { super(); } public Date(int year, int month, int day) { super(); this.year = year; this.month = month; this.day = day; } public int getYear() { return year; } public void setYear(int year) { this.year = year; } public int getMonth() { return month; } public void setMonth(int month) { this.month = month; } public int getDay() { return day; } public void setDay(int day) { this.day = day; } public boolean isLeapYear(int year) { if(year%400 == 0||(year%4 == 0 && year%100!=0)) return true; else return false; } public boolean checklnputValidity() { if (year >= 1900 && year <= 2000 && month >= 1 && month <= 12 && day >= 1 && day <= 31) { if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) { if (day > 31) return false; else return true; } if (month == 2) { if (isLeapYear(year)) { if (day > 29) return false; else return true; } else { if (day > 28) return false; else return true; } } if (month == 4 || month == 6 || month == 9 || month == 11) { if (day > 30) return false; else return true; } } return false; } public void getNextDay() { if(checklnputValidity()) { if(month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10) { if(day<31) { day = day+1; System.out.print("Next day is:"+year+"-"+month+"-"+day); } else { day = 1; month = month + 1; System.out.print("Next day is:"+year+"-"+month+"-"+day); System.exit(0); } } if(month == 4 || month == 6 || month == 9 || month == 11) { if(day < 30) { day = day+1; System.out.print("Next day is:"+year+"-"+month+"-"+day); } else { day = 1; month = month + 1; System.out.print("Next day is:"+year+"-"+month+"-"+day); } } if(month == 12) { if(day < 31) { day = day+1; System.out.print("Next day is:"+year+"-"+month+"-"+day); } else { day = 1; month = 1; year = year + 1; System.out.print("Next day is:"+year+"-"+month+"-"+day); } } if(month == 2) { if(isLeapYear(year)) { if(day < 29) { day = day+1; System.out.print("Next day is:"+year+"-"+month+"-"+day); } else { day = 1; month = month + 1; System.out.print("Next day is:"+year+"-"+month+"-"+day); } } else { if(day < 28) { day = day+1; System.out.print("Next day is:"+year+"-"+month+"-"+day); } else { day = 1; month = month + 1; System.out.print("Next day is:"+year+"-"+month+"-"+day); } } } } else System.out.println("Date Format is Wrong"); } }



第三次题目集7-2还是算日期的题目。不过与之前不同的是,这次我们需要创建一个日期类名为Date,但后年月日都是这个日期类中的私有属性,我们通过创建一个对象,构造方法来调用它的私有属性并实现程序所要实现的功能。该程序的类图如图所示,圈复杂度为29,还是使用if-else结构使用的太多了。首先创建一个类,然后创建它的属性,并构造方法,之后再Main类里面呢new一个对象,该对象拥有年月日等属性,然Date这个类中实现日期的计算。我认为这是面向对面的程序设计的开始,这个题核心算法和第二次题目集日期计算相似,更多的区别就是一个是再一个类中完成,而另一个需要两个类完成,开始有了对象的概念,我觉得我们需要从这道题中搞懂类的概念和对象的概念,这是这道题我认为最关键的需要学习的东西。
(5)
第三次习题集7-3一元多项式求导
编写程序性,实现对简单多项式的导函数进行求解。
输入格式:在一行内输入一个待计算导函数的表达式,以回车符结束。
输出格式:
- 如果输入表达式不符合上述表达式基本规则,则输出“Wrong Format”。
- 如果输入合法,则在一行内正常输出该表达式的导函数,注意以下几点: 结果不需要排序,也不需要化简;
- 当某一项为“0”时,则该项不需要显示,但如果整个导函数结果为“0”时,则显示为“0”;
- 当输出结果第一项系数符号为“+”时,不输出“+”;
- 当指数符号为“+”时,不输出“+”;
- 当指数值为“0”时,则不需要输出“x^0”,只需要输出其系数即可。
输出格式见输入输出示例。
源代码:(由于第三题难度较大,并未写完这个程序的代码)
对于第三题,我有很多感悟,首先老是说了难度比较大,建议提前做,但是我自己认为难度再大好好写几个小时也能写完,但是实际情况并不是这样的,一开始着手开始写第三题的时候没有很清晰的思路,因为老师提醒我们可以使用正则表达式,刚看完题都不知道正则表达式要用在哪,所以自己先去学习正则表达式,再学习了正则表达式之后对于该题目有了一个大致的思路,先把空格数字去掉,然后用正则表达式把整个多项式分为好几项放到一个字符数数组里,然后在对字符串数组进行操作,但是就卡在这个点,不知道为什么我把它拆开放到字符串数组时候总是缺一项,于是后面的操作也没有办法进行了。应了老师上课说的那句话,不知道是我低估你们了还是你们自己高估自己了,确实是自己高估自己了,最后时间确实不太够了,于是就没有写完这道题。只能说下次写题早一点写,提前写。
3.踩坑心得
(1)每次写完一个代码提交的时候总是以为自己都是对了,但是往往会出现很多bug,比如日期题目,第二次习题集7-5题,第一次提交的时候我以为会全队,结果提交了才发现除了验证边界值剩下的没有一个对的,刚开始很奇怪,因为我用编译器提前试了试感觉还行,最后仔细重新阅读题目的时候才发现我把n的正负记反了,于是就开始从新改我的代码,多以说阅读题目非常的重要,一定要读清楚题目,一但题目读错写完了代码在进行改正的话,就消耗了很多不必要的时间。
(2)有时候题目的输入不能直接粘贴复制进行验证第二次课堂作业那个身份证排序的题目,它输入的时候需要输入一个就输出一个,一起输入会有错误,这个也导致浪费了很多时间去找这个所谓的”错误“,所以因为代码不同,输入数据的顺序有时也不同,所以有的输入数据不能直接粘贴复制。
(3)double类型值也存在问题,double只要在一定的误差范围内就可以认为是相等,第一次习题集7-8,判断三角形是什么三角形,当比较边的时候不能直接用==来比较,而是要用一个数减一个数小于一个值,比如y*y+z*z-x*x<0.00001,因为这个细节的小点,也是想了一定时间,最后才发现这个问题。
(4)charAt问题,用charAt提取一个字符,它本身提取出来的这个字符串如果改为int型数据代表的是这个字符的阿斯克码值,比如在第二次题目集7-1当中,IP地址转化,用charAt提取出来开该字符需要减去一个”0“才能表示当前数字,例如c=(int) (c+(sgod.charAt(i)-'0')*Math.pow(2,23-i));这个点也用了一些时间才找到错误。
4.改进建议
(1)对于日期类的题目,由于if-else语句使用过多,导致圈复杂度过高,应该尽量的用swtich语句代替,减少圈复杂度。
(2)对于第三次题目集的题目,因为创建类,所以应该在类中完成该完成的功能,尽量做到一个类实现一个功能,保证类的单一功能性
(3)对于第三次题目集的7-3题目,还需要进一步完善,解决第三题,真正的掌握正则表达式
5.总结
(1)首先在题目集一中,学到了Java的基本知识,因为C语言和java还是有一定区别的,比如输入输出不同,定义一个数组的方法也不同等,了解了C语言和Java的一些不同,掌握了一些Java的基本语法,其次在题目集二中,更进一步的掌握了Java的语法,并了解了怎样构造方法调用方法,而且学习了很多对字符串的操作,了解了Java比 C语言优越的一些地方,就比如Java有很多自带方法可供你使用,比如排序不需要自己用循环写,只需要调用它的方法就可以。第三次题目集让我们开始有了对象这个概念,面向对象的程序设计,对象很重要,了解了封装性的概念,又明白了一些Java的优越性。
(2)我想针对本次第三次习题集7-3题目谈谈自己的看法,确实这道题有一定的难度,需要花费一定的时间,本身的盲目自信就使自己开始做题的时间少了许多,然后发现这道题很难做,但是一开始并没有放弃,就是想慢慢做然后把这道题做出来,但是确实是卡在了将其每一项分开放在字符串数组中这一步,这一步一卡后面很难进行,所以就一直拖着也没找到解决的办法,然后反复学习正则表达式,看卡是不是自己的正则表达式写错了,之后所剩时间确实没有多少了,一看很多人也没有完成,就心生了一种侥幸心理,就觉得大家很多人都没有完成,也没啥事情,但是之后听老师讲过,说我们就没有那种一定要把这道题做出来的决心,想想自己确实是,没有这种决心。每次也是看看室友写了多少,看看提交名单大家都写了多少,我觉得心态挺重要的,我认为以后一定要改正这种心态,就抱着一定要去把这道题做出来的决心去做题。真的是不能怕难,如果一遇到难得题就不写了,确实什么新东西也学不到,调整心态,继续加油吧!
(3)教学方面,我就是希望老师也能对于难的题目进行一个稍微的讲解,有时候一些东西自己想确实想不明白,需要点一下,一点可能就通了。
浙公网安备 33010602011771号