OOP第一阶段(前三次作业)总结Blog1
21201313-刘聪
- 前言:开学大概两个月,JAVA的第一段学习已经结束,于此进行知识点,题目自我分析。
(1)第一次作业难度上相比于其他几次较小,故题目量相对较多。对于刚学习JAVA的我来说,与上学期C语言作业几乎差不多,但是值得注意的是,第一次作业的输出格式要求严格苛刻,测试点比较难过。从作业一中,可以收获一些JAVA的新东西。
(2)第二次作业相对难度较有提升,题目中的逻辑与判断逐渐复杂,也对JAVA中的我不认识的新函数以及新知识考察运用。譬如对String类中substring、indexOf函数的学习和运用,期限并不知到有此类函数所以做起来毫无头绪,但明白函数后题目就变得容易了;又如第二次作业的第二题,关于“奇偶校检位”的知识,通过浏览器学习得以了解。
(3)第三次作业可谓是开学以来的作业噩梦级别,只有三道题目,但是题目错综复杂,细节繁多,考察点与测试点细致,导致做题无数次错误无数次。现在分析,这三道题目层层递进,进一步的体现了JAVA中的类的构造与运用,第三题可以称是在前两道题目基础上的结合与升级,且对数据处理有更大的要求,这是第三次作业的关键。对于第一题,我认为是处理后续题目的基础,主要是对字符串的判断与提取,细节方面以及对所有可能出现的情况考虑尤为重要;对于题目二,可以说,若第一题能将全部测试点通过,第二题不会太难,无非就是数学上的算法难度,以及多种情况分类处理。第三道题目是最难最有挑战性的一题,考察了对前两题所创建的函数与类的运用,以及数学上对线、三角形的关系的判断与运算。很遗憾的是我没有把所有测试点过完,在开始写代码的时候就没有想好全局,导致做到后面的要求时无从下手,越改越乱,得分越来越少,直到作业截止。这次作业给我的教训是,在编写代码前应瞻前顾后,领略全局再下手,如果走一步试一步最后很难完成题目要求。因此在下一阶段的学习我更要提升自己,巩固知识,认真分析再下手。
- 4例题目 设计与分析 踩坑心得 改进建议
(1)PTA大作业二 7-2(串口字符解析):
设计与分析
这道题目刚上手还是一脸茫然的,原因题目太长并且包括一些不了解的知识,仔细阅读后才能找出突破点,需学习奇偶校检才能做。
踩坑心得
private static boolean check (String c) { boolean flag = false; int j=0; for(int i=0;i<c.length()-1;i++) { if(c.charAt(i)=='1') j++; } if(j%2==1) flag=true; return flag; }
这部分代码为奇校检的一个函数,值得注意的是,应题目要求加上有效数位后一位,刚开始测试点一直过不了就是因为这个坑。
改进建议
由SourceMonitor以及PowerDesigner软件测评结果可以看到,这段程序复杂度高,且都在主类中完成。这段效率效率不是很高,因为此题我只用了一个主类执行,在主函数里面用了过多的if条件语句,导致程序复杂。另一个不足之处就是在某种数据下可能会出现字符串越界的情况,但是能运行给出结果,暂时还不明白原因。究其原因,是我写代码不够精练,应继续提升,通过将提取字符的方法从主类中拿出来建立新的类,以方便找出错误。
(2)PTA大作业三 7-1(点线形系列1-计算两点之间的距离):
设计与分析
这次作业的第一道题目,由于主要就是对字符串的格式判断以及提取,仅一个主类,写的时候分了两个函数,一个是对格式判断的boolean的函数,一个是对结果的计算的double函数。首先题目要求,判断输入的字符串是否合法,若不合法则输出Format Wrong;再判断所输入的点数是否正确,若不正确则输出Wrong of number points;最后在结果计算之前,需要将输入的各个点提取出并转化成double类数据。
踩坑心得
int m = 0; for(int i=0; i<s.length(); i++) { if(s.charAt(i)==' ') m++; } int n = 0; for(int i=0; i<s.length(); i++) { if(s.charAt(i)==',') n++; } char[] str = new char[m+n]; int p =0; for(int i=0; i<s.length(); i++) { if(s.charAt(i)==',' || s.charAt(i)==' ') { str[p]=s.charAt(i); p++; } }
截取main中的一段代码,这里是做了第二天才想到的坑,即所输入的点中,点与点必须用空格符号“ ”隔开,而点内部的横坐标和纵坐标又要用英文符逗号隔开“,”,这就导致输入时的不规范情况增加,譬如将“ ‘ “ ,”换成” “等不规范格式,需要去测试。想了许久才想出用一个字符串数组将逗号与空格存储,再判断是否”,“后面为” “,” “后面为”,“,若无这个判断,测试点的case7过不去。
还有一个大坑便是输入的数据中,“0”在首位时后面再接一个“0”的话也是格式错误,这个点很难发现,因为将字符串转化为数字的Double.paraseDouble()函数可以将这样的字符串转化成数字,不经一番推敲很难发现这种情况。
改进建议
由总体代码可以看到,我在判断输入的数据是否合法时,在主函数前进行了一次空格与逗号的判断,在提取之前又用istrue()函数进行了对每个点是否合法的判断,这里就把代码无理由的复杂化,并且不利于其他程序对这段代码的采用。我认为可以改进的是将两段判断格式的代码合在一起并建立一个关于输入点的字符串的类,在这个类中直接进行所有的格式判断。由于后续要用到这个类,这里提出的类在后续题目还要用到,可以在这个类中添加一个判断并返回点数点数的方法。
(3)PTA大作业三(点线形系列2-线的计算)7-2:
设计与分析
第二题开始题目复杂程度剧增,并且对数学能力要求提高。题目继承上一题,依旧输入一串字符串,判断格式,并提取进行计算。与上一题不同且难度提升的是,这题多了其他更多点的情况,譬如点与线、线与线的关系以及计算。需利用7-1中的类来处理输入的字符串,再在主类中进行运算输出。这里增加复杂性的是,两个点时,计算斜率,并且还应判断斜率不存在的特殊情况;三个点时,又有两种情况判断,一种计算点到直线的距离,一种判断三点是否在同一条直线;四个点时,又有两种情况,一种判断两条直线位置关系,一种判断交点,而第二种又分有几种情况。题目存在的情况繁多复杂,需仔细一一分析,否则很容易出错。
踩坑心得
if(xy[4]!=xy[6]) { double x=(xy[5]*xy[6]*xy[2]-xy[7]*xy[4]*xy[2]-xy[5]*xy[6]*xy[0]+xy[7]*xy[4]*xy[0]-xy[1]*xy[2]*xy[6]+xy[3]*xy[0]*xy[6]+xy[1]*xy[2]*xy[4]-xy[3]*xy[0]*xy[4])/ (xy[6]*xy[3]-xy[6]*xy[0]-xy[4]*xy[3]+xy[4]*xy[1]-xy[2]*xy[7]+xy[2]*xy[5]+xy[0]*xy[7]-xy[0]*xy[5]); double y=(-xy[5]*xy[6]*xy[3]+xy[7]*xy[4]*xy[2]+xy[5]*xy[6]*xy[1]-xy[7]*xy[4]*xy[1]+xy[1]*xy[2]*xy[7]-xy[1]*xy[2]*xy[5]-xy[3]*xy[0]*xy[7]+xy[3]*xy[0]*xy[5])/ (xy[7]*xy[2]-xy[7]*xy[0]-xy[5]*xy[2]+xy[0]*xy[5]-xy[3]*xy[6]+xy[3]*xy[4]+xy[1]*xy[7]-xy[1]*xy[4]); boolean fla=true; double max=Math.max(xy[0], xy[2]); double min=Math.min(xy[0], xy[2]); double max1=Math.max(xy[4], xy[6]); double min1=Math.min(xy[4], xy[6]); if((x>max||x<min)&&(x>max1||x<min1)) fla=false; System.out.print(x+","+y+" "+fla); }
从这题开始,所需改进的地方越来越多,譬如上图代码,是计算当两条斜率都存在线的交点时的交点时的计算代码,这里被我写的错综复杂,如果出错了是很难检查出哪里出错了的,建议改进的就是用更合理靠谱的新方法,或者先用变量储存较长数据再进行计算。还有一个坑,便是计算时候要判断直线斜率是否存在,可以在计算之前就判断,那样在后面计算的时候就不用写太多笼长的if、else的“套娃式”代码来判断计算与输出。
改进建议
对于这题的改进,便有多处文章可作了。首先,题目较复杂,应该建立一个“线的类”用于传入数据,在类中写一个方法求斜率的方法,一个求与另一条线求交点的方法,一个判断与另一条线是否平行的方法,以及求点到线距离的方法,这是第一点,可以将我之前三四百行的代码缩短大半。再者,如果在7-1题目中建立了关于字符串的类的话,可以简便的使用其创建对象,以化简代码。可以说这就是实际存在的一步错步步错吧,之前没有建立类,到后面一直没有,代码乱了起来,导致后面还有一个测试点过不去但是检查不出来,实在惭愧。
(4)PTA大作业三(点线形系列3-三角形的计算)7-3:
设计与分析
这是这些题目中最难最复杂的一道题目,需要在前几题的基础上进行对三角形相关的计算,在进行关于三角形计算之前,应有一个能判断三点是否能构成三角形的函数。当输入三个点时,有三种情况,求三角形类型(等腰、等边、直角、锐角、钝角)求三角形面积、周长、重心坐标;当输入五个点时,求线与三角形的关系;当输入四个点时,利用射线法求点是否在三角形内部。需要分多种情况进行编程以及计算。通过sourcemonitor软件分析图的结果来看,我的代码是一段繁杂超长的代码,结构复杂无规则,没有合理利用类进行编程。
踩坑心得
else { double aa=Math.sqrt( Math.pow( (xy[0]-xy[2]),2 ) + Math.pow((xy[1]-xy[3]),2) ); double bb=Math.sqrt( Math.pow( (xy[0]-xy[4]),2 ) + Math.pow((xy[1]-xy[5]),2) ); double cc=Math.sqrt( Math.pow( (xy[2]-xy[4]),2 ) + Math.pow((xy[3]-xy[5]),2) ); double zouchang = aa+bb+cc; double zhx=(xy[0]+xy[2]+xy[4])/3; double zhy=(xy[1]+xy[3]+xy[5])/3; double ss=(xy[0]*xy[3]-xy[0]*xy[5]+xy[2]*xy[5]-xy[2]*xy[1]+xy[4]*xy[1]-xy[2]*xy[3])/2; if(decimal(zouchang)>6) { zouchang=(int)(zouchang*1000000+0.5)/1000000.0; } if(decimal(zhy)>6) { zhy=(int)(zhy*1000000+0.5)/1000000.0; } if(decimal(zhx)>6) { zhx=(int)(zhx*1000000+0.5)/1000000.0; } if(decimal(ss)>6) { ss=(int)(ss*1000000+0.5)/1000000.0; } System.out.print(zouchang+" "+ss+" "+zhx+","+zhy); } }
对于这个坑,我觉得应有的说,改进之后可以简化代码。这是一段保留六位小数并且四舍五入的代码,我的程序中没用方法写出来,而是直接在输出之前进行转化,这样就增加代码复杂度。并且在题目几处都要用到这个计算方法,若改成一个方法,可以简化代码,减少代码复杂度以及行数。对于后续关于三角形的计算,由于题目情况较多,应巧用类与对象与方法进行编写缩短代码。我的代码最大的的不好的地方就是没有有效的利用类建立对象,使后面的代码复杂写不下去,这是一个慎入的大坑。
改进建议
改进的方面就是多建立几个类,对于要重复使用的部分应建立并使用方法。承接前面两题,建立一个字符串的类,一个线的类,再新建立一个三角形的类。对于三角形的计算,多创建对象进行运算。再者,对于要重复使用的计算类型,应当建立一个公用的方法,对此调用时方便简洁美观。对于后面比较难计算的数学类题目,应先在浏览器找并到学习简便的方法,再进行编程。说来惭愧的是,由于时间与能力的问题,我的代码并没有圆满完成题目的需求,此处反思即改进并提出建议。
总结:
(1)在第一阶段的学习中认识了面向对象这个概念,与上学期的C语言颇为不同。虽说所学知识较为基础,但相比起来,java的花样比较多,比较灵活实用。
(2)这阶段的学习中,认识了类、类与类之间的关系,类与对象的关系。学会了如何去利用类与对象以及其中的方法,将代码简化写简洁,避免产生垃圾代码。
(3)在这几次作业中,体会到了先分析全局在写代码的重要性,在写代码时先想好全局以免后续出了问题不知从何改起。若没有提前构思好写一步是一步的话,最后发现问题很难回头。
(4)通过这次的练习,得知了自己学习的还是太少了,应看重课堂的仔细听课,课后多做练习并且了解知识点,巩固基础,提升自己。
(5)这阶段学习,学到了一个很重要的函数split(),为提取便利了很多;学到了一个方便且重要的类ArrayList<String>。
(6)在面向对象这方面我还应该努力学习与适应,提升编程能力。
(7)感谢OOP课程老师的指导与作业监督,虽然过程很累,但还是得向前看,迎接第二阶段的学习。