前言:
第一次作业
第一次题目较为简单,主要练习我们在面向对象语言中类和对象的使用。八道题数量虽多但是题目较为简单。以下为第一次作业的知识点整理:
1)类和对象的使用:
类包括属性和方法。类是较为抽象的一个概念,在通常情况下,一个类并不能直接使用,需要通过类创建一个对象才能使用。
对象需要导包和创建,创建也就是我们平常所说的new一个类名称。需要注意的是,在处于同一个package下导包语句可以省略不写。
2)强制类型转换(7-5):
1 Scanner sc = new Scanner(System.in); 2 3 double money = sc.nextDouble(); 4 5 System.out.println((int)money/10+" 张十元");
3)其中7-2用到了ASCII码转换。
4)创建一维数组:
1 Scanner sc = new Scanner(System.in); 2 3 int n = sc.nextInt();//输入的数字个数 4 5 int[] arr = new int[n];
第二次作业
相较于第一次难度有所提高但多多完善自己的代码还是可以完成的,但是程序需要考虑的小点很多,在提交后看到有部分测试点没有通过再修改代码的时候,程序基本逻辑多多少少会被破坏,可读性不高。
1)IP低址转换(7-1)中用到的方法的具体用法:
pareInt(String s):将字符串s转换为十进制的数字,默认为十进制
pareInt(String s,int redix)redix代表转换的进制,不写默认为十进制。
2)判断闰年:
①是4的倍数但不是100的倍数②400的倍数
(year % 4 == 0 && year % 100 != 0 )|| year % 400 == 0
3)后两题注意+1/+n天以后,跨月、跨年的情况以及闰年及非闰年在2月份跨月的情况。
第三次作业
前两题难度不大,但是第三题对于我而言有点难度,最后也只是通过了部分测试点。
1)封装:
Java的三大特性之一(封装、多态、继承)。
封装是将类的信息隐藏在类的内部,不允许外部程序直接访问,而是通过该类的方法实现对隐藏信息的操作和访问。
方法其实就是一种封装,间接访问private成员变量,就是定义getter(不能有参数)/setter(不能有返回值)。
封装的实现:
①修改属性的访问控制符(public-private);②属性的读写:创建getter/setter方法;③判断属性值的合法性:在getter/setter方法中加入属性控制语句。
2)Java中public、private的区别:
Public:具有最大的访问权限,可以访问任何一个在classpath下的类、接口、异常等。往往用于对外的情况,也就是对象或类对外的一种接口的形式。
Private:访问权限仅限于类的内部,是一种封装的体现,大多数成员变量都是修饰符为private的,这些不希望被其他任何外部的类访问。
3)this.的用法:
当方法的局部变量和类的成员变量重名时,优先使用局部变量。如果使用本类中的成员变量。格式:this.成员变量名。
作业过程:
题目集1
7-8判断三角形类型
设计与分析:
与本题思路很简单,输入a.b.c三条边,通过各类三角形的三遍关系,用if else 语句来进行三角形的判断。
采坑心得:
错误一:在判断直角三角形判断条件为a^2+b^2 = c^2时,由于pta不能输入平方,所以导致不能正常对直角三角形、等腰直角三角形进行测试。
将判断语句修改为:a*a+b*b-c*c>=0 && a*a+b*b-c*c <0.0001即可正常对直角三角形进行判断。
错误二:要先判断等腰直角三角形,再判断直角三角形和等腰三角形。如果是先判断了直角三角形或者等腰三角形,且输入的是等腰直角三角形,那么输出的答案就会是直角三角形或者等腰三角形。一定一定要注意先写小范围再写大范围。
错误写法:
1 if(a + b > c && a + c > b && b + c > a){//三角形两边之和大于第三边 2 3 if(a == b && a == c){//等边三角形 4 5 System.out.println("Equilateral triangle"); 6 7 } 8 9 else if(a == b || a == c || b == c){//等腰三角形 10 11 System.out.println("Isosceles triangle"); 12 13 } 14 15 else if(a*a+b*b-c*c>=0 && a*a+b*b-c*c <0.0001){ 16 17 if(a == b || a == c || b == c){ 18 19 System.out.println("Isosceles right-angled triangle");//等腰直角三角形 20 21 } 22 23 else 24 25 System.out.println("Right-angled triangle");//直角三角形 26 27 } 28 29 else//一般三角形 30 31 System.out.println("General triangle"); 32 33 }
输出结果:
正确写法:
1 if(a + b > c && a + c > b && b + c > a){//三角形两边之和大于第三边 2 3 if(a == b && a == c){//等边三角形 4 5 System.out.println("Equilateral triangle"); 6 7 } 8 9 else if(a*a+b*b-c*c>=0 && a*a+b*b-c*c <0.0001){ 10 11 if(a == b || a == c || b == c){ 12 13 System.out.println("Isosceles right-angled triangle");//等腰直角三角形 14 15 } 16 17 else 18 19 System.out.println("Right-angled triangle");//直角三角形 20 21 } 22 23 else if(a == b || a == c || b == c){//等腰三角形 24 25 System.out.println("Isosceles triangle"); 26 27 } 28 29 else//一般三角形 30 31 System.out.println("General triangle"); 32 33 }
输出结果:
改进建议:
这道题思路就是使用if else判断,需要注意的是先写小范围判断条件再写大范围的判断条件。
题目集2
7-4求下一天
设计与分析:
此道题先考虑题目给出的年月范围,还有要注意隐藏关系日期,每个月份日子可能不相同,在这里我采用的是通过一维数组,将每个月的最大天数存进数组,判断闰年时,改变二月份的天数。如果+1天以后在月中,天数直接+1就好,这道题难点在于如果遇到月末及年末,需要注意月份和年份也要随之变化,闰年二月底和非闰年二月底也要注意。
采坑心得:
错误一:我一开始想用月份作为if else的判断条件,计算每个月中可能出现的情况,但是输入pta上显示代码长度过长不能提交,所以换了一个思路,把day+1作为判断条件(跨月、跨年的情况单独考虑),最终测试通过。
注意一:我当时写的时候并没有注意,在判断闰年及非闰年时候,一直在重复最基本的判断条件(year % 4 == 0 && year % 100 != 0 )|| year % 400 == 0,但其实在前面已经声明了isLeapYear的方法,直接用就行啦但是忘了导致代码可读性降低。
应该这样写就易懂许多:
1 else if(isLeapYear(year)){ 2 3 if(month == 2 && day == 29){ 4 5 day = 1; 6 7 month = month + 1; 8 9 System.out.println("Next date is:" + year + "-" + month + "-" + day); 10 11 }
注意二:在跨月、跨年时候,注意月份、年份+1。
1 else if(day == MONTH[month]){ 2 3 day = 1; 4 5 month = month + 1; 6 7 System.out.println("Next date is:" + year + "-" + month + "-" + day); 8 9 } 10 11 else if(month == 12 && day == 31){ 12 13 year = year + 1; 14 15 month = 1; 16 17 day = 1; 18 19 System.out.println("Next date is:" + year + "-" + month + "-" + day); 20 21 }
改进建议:
这道题把闰年另外写一个方法内然后调用,在if else判断闰年时就不会太过冗杂不好观看。
7-5求前N天
设计与分析:
这道题其实和7-4求下一天有点类似,同样的也是要注意+n天跨月和跨年的情况,月份及年份也会变化。其次这道题还需要注意n的范围,n不能任意取值。
采坑心得:
错误一:假设日期为2001年6月6日,当n = 2时,取的是此日期的前两天,即2001年6月4日,当n = -2时,取的是此日期的后两天,即2001年6月8日。当时因为没有注意n的正负情况是加还是减,导致日期取反了,运行结果错误。
错误二:这一次题目相较于前面一道题考虑的情况会更多一些,一开始在提交代码后纸通过了部分测试点,于是我只是把自己没有通过的测试点通过if else语句直接加在了原有代码上,但是这样其实对整体代码的逻辑很不友好,当第二次再读代码时,代码可读性大大降低,让人摸不着头脑。所以遇到测试点通过不了的问题的时候,还是需要重新思考这道题的思路与逻辑重新构思。
改进建议:
在没有通过部分是测试点的时候,我只是在自己原有代码的基础上直接加上了测试点没有通过的部分代码,虽然测试点顺利通过但是导致代码逻辑过于混乱,在之后又重新梳理了思路写了以下:
题目集3
7-2定义日期类
设计与分析:
这道题本来是想考察我们面向对象思想中的封装,包括public和private的区别,以及如何创建getter/setter方法,但是当时我写作业过程中没有用题目要求的方法,而还是用了面向过程语言中的思路与方法,代码冗杂且不易读。
按照面向对象思维的核心代码如下:
以下为声明私有private以及getter/setter的无参构造方法及有参构造方法。
1 private int year; 2 private int month; 3 private int day; 4 5 public Date(){//无参构造方法 6 } 7 public Date(int year,int month,int day){//有参构造方法 8 this.year=year; 9 this.month=month; 10 this.day=day; 11 } 12 public int getYear(){ 13 return year; 14 } 15 public void setYear(int year){ 16 this.year=year; 17 } 18 public int getMonth(){ 19 return month; 20 } 21 public void setMonth(int month){ 22 this.month=month; 23 } 24 public int getDay(){ 25 return day; 26 } 27 public void setDay(int day){ 28 this.day=day; 29 }
另一部分为day+1天的表述,思路和第二次作业的求下一天是一样的。
1 //day+1 2 if(day<a[month]){ 3 day=day+1; 4 System.out.println(year+"-"+month+"-"+day); 5 } 6 //月末+1 7 else if(day==a[month]&&month!=12){ 8 month=month+1; 9 day=1; 10 System.out.println(year+"-"+month+"-"+day); 11 } 12 //年末+1 13 else if(day==a[month]&&month==12){ 14 year=year+1; 15 month=1; 16 day=1; 17 System.out.println(year+"-"+month+"-"+day); 18 }
采坑心得:
这道题可以有两种方法,一种是面向过程,中间核心代码还是像C一样使用,另外一种是面向对象,也就是使用封装,使用私有属性private来构造。
改进建议:
这次作业的题目主要锻炼我们面向对象的思维,千万不可偷懒继续使用面向过程思维,通过第三次作业的7-1与7-2题目,让我对private和getter/setter的使用更加熟练。
7-3一元多项式求导(类设计)
设计与分析:
这个题目对于我而言有挑战性,题目要求自学正则表达式来检验表达式的合法性,同时要注意输入空格的情况,如果输入字母和符号中间有空格的话,忽略空格继续进行计算。建议使用ArrayList,数组的长度不可以发生改变但ArrayList集合的长度是可以随意构造的。
采坑心得:
这次作业有一点难度,其中有一半的测试点未通过,对于输入案例中带空格的情况不能正常运行,还是会输出wrong format。
改进建议:
第三题是较为综合的一道题目,其中需要自学正则表达式,还要使用私有属性private以及创建getter/setter方法。
总结:
第一二次作业的代码我还是面向过程的编程思维,并没有做到面向对象编程,作业的题目基本都是用if else可以解决的,其实还是C语言的内容。第二次作业关于天数的几道题(判断闰年及星期几、求下一天、求前N天),我有很多测试点是提交代码以后显示答案错误,在原代码的基础上继续改的,造成整体代码思路很乱,如果回过头来看的话思路太不清晰,所以以后还是要捋清思路再下手敲,避免很多情况没有被考虑。第三次作业第一题创建Account类,第二题创建Date类,这两题本是考察我没对于面向对象思考的理解及对于封装的使用,但是第二题偷懒了并没有创建类也没有用到封装。第三题太难啦测试点只过了部分测试点。
这三次作业难度依次提高,但是题目也是有针对性的对我们的各个方面进行练习,只有通过自己敲代码的过程中发现了问题,才会对这个问题印象深刻,以后的学习过程中才不会出现类似的问题。