OOP课程第一阶段总结Blog
OO课程第一阶段(前三次作业)总结Blog1
20201328-严振轩
- 前言:学习OOP课程的第一阶段已经结束了,在此进行对于知识点,题量,难度的个人看法。
(1)第一次作业基本上是基本的编程的语法训练,题量大,难度小,利于我们熟悉Java的基本语法:输入,输出,if语句,for循环等;
(2)第二次作业有些许难度上的提高,提高在需要自己去学习新的知识点:进制转换,sort排序算法等,以及加深考察编程的细节:日期问题的迭代,注重基本的问题分析。
(3)第三次作业才开始展现出与C语言不同的编程方式,对于类的构造,运用,是这次作业需要掌握的内容。三道题目,简单的类运用,其中前两道完成的较为轻松,只需要了解并基本运用类构造
与类的使用,便可以在第二次作业的基础上,完成迭代升级。但第三道题,难度急剧上升,从答案提交的通过率来看,2000多次的提交,仅仅只有20次左右的成功。而难的原因在于四点:第一是需要学习正则表达式才能最高效的完成该题;第二是知识点的综合运用,不仅仅需要类的知识,还需要大数,字符匹配,替代等方法去辅助题目的完成,其中许多的细节性的问题难以把控。第三是题目测试点的问题,过多的时间在钻题目测试点的牛角尖,而没去仔细阅读指导书,导致许多时间浪费在合法性测试上,对自己的代码也是越改越乱。最终是未达到满分遗憾结束。第三次作业是从一开始的自信到不敢相信,这也更加让自己认识到自己所学的一切还是太少了,需要在下一阶段高强度学习。
- 各题目 设计与分析 采坑心得 改进建议 :
(1)题目集1:7-8 判断三角形类型
设计与分析
因该题较简单,不需要构建多个类去完成,仅仅是通过简单的主函数便可以完成全部的功能,首先通过冒泡排序筛选出最大边与最小边,放入有序数组中,再通过对于判断条件的计算,得出初步结论,判断受否合法,再之后便通过大量的if语句完成了全部情况的概括,虽然形式简单,但是还是出现了对bug的不断调试。以下阐述我的采坑心得:
采坑心得
以此部分为例子,但凡判断直角三角形情况,都需要去用勾股定理进行计算判断,而最开始的设计便是勾股定理的等式设计,导致输出结果有误,后查找其他博客的资料发现,Java中浮点计算存在精度丢失问题,若
通过等式去验证勾股定理,则会导致浮点计算错误,验证失败。后调试为<0.0000001(小数点几位都可以),则可以通过直角三角形的验证。这个坑困惑了我很久,因坚信着数理逻辑不可能出错导致对自己的代码非常自
信,以至于半天找不出问题,后发现需要去了解浮点计算的本质,才能正确解题。
改进建议
由SourceMonitor以及PowerDesigner软件测评结果可以看到,该代码存在两个问题:1.复杂度对于这样的问题是偏高的,需要优化;2.题目简单,导致只有主类,看着也十分直白。改进建议:减少if语句的使用,既然已经知道了情况的可能性,便可以通过使用switch语句去指定进行输出,甚至可以对数据进行统一的计算处理,再进行一一对应到switch中,这样可以大幅降低复杂度,代码运行的效率更高。若是想处理的更为体现类的形式,可以将数据计算处理在一个计算类中,判断条件写在判断类中,结果输出写在一个输出类中,这样可以将题目处理的更有可读性。
补充:对于筛选出最大边的排序问题,可以采用sort排序法,利用Java自带的方法完成排序。
(2)题目集2:7-4 求下一天
设计与分析
该题目是输入一个日期求它的下一天,改题目需要首先根据题意划定合法范围,选择是否输出为“Wrong Format
”,若判定为正确输入后,根据boolean判断闰年,以及是否为月份的边界的点,是否为跨年情况,是否是闰年2月跨月,平年2月跨月,综合全部的情况,得到一个结果。设计之初是想法很多,认为情况太多,最后也是一一把每种情况都描述清楚。所用的大部分为if语句,这大大增多了复杂度,但在当时,脑子里也只有这种直来直往的想法,后续会阐述出我现在的优化想法。
采坑心得
因为当时在此题是第一次使用boolean语句,刚从网上看了些皮毛就开始动手,导致根本没有理解boolean类型,返回的一直是自己所做的正误标记,一直报错,后修改为返回true或者false;将二者在本题返回的题意正确与否弄反,一直过不了测试点,后发现后及时调整,完成了该题。
改进建议
由SourceMonitor以及PowerDesigner软件测评结果可以看到,这段程序复杂度高,且都在主类中完成。这是段效率不高的代码(由自己提交题目时,偶尔会出现运行超时可以看出),究其原因,是因为if语句过多,导致程序运行的过于拖沓,后参考其他人博客发现,可以采用switch语句,复杂度可以大幅降低。其次,对于判断闰年,判断边界条件等功能,可以在另一个新建的类进行统一处理,通过建立year,month,day私有属性,即可在一个类中利用不用的方法,完成功能,在通过string tostring语句完成对结果的输出。这样的类构造可以大幅提高代码的可读性。
(3)题目集2:7-5 求前N天
设计与分析
本题目与7-4有异曲同工之处,基本上可以去套用7-4的代码,只是多了一个前n天对于n的主观输入,该n给定了-10到10的范围,使得题目不会过于复杂。该题目也是要考虑闰年2月跨月情况,以及跨年情况,再者就时遗漏的7,8月情况,跨这两个月份要与其他月份分开讨论,以下采坑心得会仔细解析我的入坑点。总而言之,这是个需要对多种情况考虑的题目,若有遗漏,则会造成输出结果有,但不是正确结果。本题还是最基本的一些知识的综合:基本语法,闰年判断,if语句调用,for循环等,类的思想并没有体现。
采坑心得
该题目一开始是进行非2月的月份,分日数为31天与30天的分开统一处理,进行统一的跨月处理。后发现一个8月份的跨年测试点无法通过,才发现7,8月连月的情况,需要分开处理。例如若默认31天后为30天的月份,则会导致7到8月的跨年出错。所以这边多在原有的判断语句中,加了一种情况的考虑,即在7,8月的连月跨年情况进行了完善。这个坑点不在于Java本身的语法错误,逻辑错误,更多是在对于数学细节的处理不够到位,在处理数据不多的情况下,不仅依靠规律性,更可以自己尝试遍历测试,发现细节。
改进建议
由SourceMonitor以及PowerDesigner软件测评结果可以看到,改题目复杂度高,且没有用类完成。为了降低复杂度而言的话,也如7-4的处理情况,可以尝试使用switch语句完成。若可以将对于year,month,day的处理放在一个类中,完成对于闰年的判断(类方法),再者通过对month,day以及输入的天数,在不同的月份的处理上,通过switch语句完成不同情况的处理,再者通过String tostring()进行结果的输出,这样主类仅是new一个新对象后,便可以通过调用方法,完成题目。这样类的功能分工明确,且代码复杂度减少,效率上升。
(4)题目集3:7-2 定义日期类
设计与分析
本题目题目集合2 7-4日期题目的迭代,本次老师要求要创建一个Date类,主类仅仅进行日期的输入,以及new一个对象,通过Student类中的各种方法,求出题目所需的下一天。本题目的设计,老师在pta中给出了类图,根据类图,完成设计根据类图还是轻松的,在题目集2的基础上,调整为类设计,虽然类设计的简单,但是也是作为基础,熟悉了类的构造与运用的方式。设计类含有对闰年判断的方法,以及对数据处理后,输出吓一天的方法(String 型的方法),在主函数仅仅是new出对象后,便可在Date类中完成判断与输出。
采坑心得
1 String getNextDate(){ 2 if((isLeapYear(year)&&day<29)||(!isLeapYear(year)&&day<28)) { 3 System.out.println("Next day is:"+year+"-"+month+"-"+(day+1)); 4 5 } 6 else if(month==12&&day==31) { 7 System.out.println("Next day is:"+(year+1)+"-"+"1"+"-"+"1"); 8 9 } 10 else if((month==1&&(day>0&&day<31))||(month==3&&(day>0&&day<31))||(month==5&&(day>0&&day<31))||(month==7&&(day>0&&day<31))||(month==8&&(day>0&&day<31))||(month==10&&(day>0&&day<31))||(month==12&&(day>0&&day<31))) { 11 System.out.println("Next day is:"+year+"-"+month+"-"+(day+1)); 12 13 } 14 else if((month==4&&(day>0&&day<30))||(month==6&&(day>0&&day<30))||(month==9&&(day>0&&day<30))||(month==11&&(day>0&&day<30))){ 15 System.out.println("Next day is:"+year+"-"+month+"-"+(day+1)); 16 17 } 18 else if(month==2&&day==28&&(!isLeapYear(year))) { 19 System.out.println("Next day is:"+year+"-"+(month+1)+"-"+"1"); 20 21 } 22 else if(month==2&&day==29&&(isLeapYear(year))) { 23 System.out.println("Next day is:"+year+"-"+(month+1)+"-"+"1"); 24 25 } 26 else if((month==1&&day==31)||(month==3&&day==31)||(month==5&&day==31)||(month==7&&day==31)||(month==8&&day==31)||(month==10&&day==31)||(month==12&&day==31)) { 27 System.out.println("Next day is:"+year+"-"+(month+1)+"-"+"1"); 28 29 } 30 else if((month==4&&day==30)||(month==6&&day==31)||(month==9&&day==31)||(month==11&&day==31)) { 31 System.out.println("Next day is:"+year+"-"+(month+1)+"-"+"1"); 32 33 } 34 return null; 35 }
以上代码为Student类的输出日期的方法,在初期只是简单的去尝试在类中完成输出结果的展示,后发现无法将输出结果传回主函数中完成输出。后通过菜鸟教程学会了String型的类方法,可以直接返回字符串的输出结果,仅通过在主函数住new一个对象调用该String方法,便可以在主函数中完成输出结果。这大大减少主函数的代码负担,若不知道这样处理,则可能还会将这亢长的输出代码写在主函数中,则代码的可读性大大降低。这样也会给之后的代码些许启事,多学有益。
改进建议
该代码可以说是在以上题目集2 7-4日期题中修改建议的方式改进而来。即通过构建了Date类完成了判断,数据处理以及输出。但通过SourceMonitor以及PowerDesigner软件测评结果可以看到,复杂度依旧高,这让我不得不想到代码本质还是由众多if语句构成,这是降低复杂度上的绊脚石。在不同的月份的处理上,其实可以通过switch语句完成不同情况的处理。若脱离老师的要求,可以去使用Java中和日期相关的类和方法,这可以把复杂度降低最大化。由此可以想到,若把题目集2 7-5 的题目放至此题完成类的聚合,则会使日期类的题目归于一体,这是后续可以去尝试的地方,也是类的升级使用,进一步体现Java面向对象编程。
(4)题目集3:7-3 一元多项式求导(类设计)
设计与分析
该题目的大致需求是:使用类与对象编写程序对简单多项式的导函数进行求解。通过设计主类:完成对于多项式的输出;再者构建多项式类:通过正则表达式完成对指数,系数的解析,分别将系数,指数放入不同的方法中进行处理,后完成综合处理,该处理主要体现在求导后指数与系数的变化。变化后的数据储存在动态数组之中。最后通过求导类的综合判断(包括列式的合法性,单个多项式的合法性,以及去x的情况等)得到多个一项的多项式,最后通过一个连接类将所有式子连结起来形成所需要输出的求导后的式子。本题的难度首先就是对于正则表达式的学习,正则表达式运用的意义在于判断输入式子的合法性,以及拆分多项式系数与指数的作用。看似简单的式子,是需要自己学习并写出来,为此需要到正则表达式网站进行多次的测试。若可以完成拆分,则需要对指数系数做出不同情况的处理(例如-1 +1)的情况,这是令人头疼的一点。为此需要多方考虑后得到一个统一的解决方式,即写出一个求导类方法:针对不同情况得到求导后的指数与系数。最终通过字符串连结,成求导后的多项式。
采坑心得
1.
该处正则表达式是不规范的,它所能匹配到的是单个多项式,但问题出在若出现x项或者中间出现常数项,则会匹配出错,这让我改变的写法。改变写法如下。
该多项式便可以完成对输入多项式合法性的基本校验。
2.合法性校验测试:
因没有仔细阅读指导书,则在一个多项式中出现多个一次幂多项式求导时,会出现常见的写法如下:
而所需要的合法性检验的写法却如下:
虽然不符合平常写法,但这是指导书中所提示的,众多同学包括我也是因这个合法性测试,而卡了许久,以至于重构代码也没效果,后发现问题因于此。
改进建议
本次代码我使用的类设计还是略微简陋的,虽然都有很明确的分工,但是类与类直接互相调用则会偶尔导致无法生成正确结果。并且在开头为负数的测试点上,我的代码也是一直无法通过,这是令人痛苦的,痛苦在自己的代码虽然进行了类的分工,但却不知出在哪一步上。在通过上一次实验发现,这其实可以用断点调试的方式,去看到进程哪一步出错。其次则是在正则表达式上,本人的正则表达式多少还存在点缺陷,例如中间出现常数,则极大可能出现无正确结果的现象。经过思考,发现其实可以在拆分处多个单项式时,便开始进行求导处理,处理完一项再去处理下一项,最后连结起来。而我所做的代码,则太关注于对指数与系数的细节处理,以至于大体的求导,会容易出错。最后就是类设计的缺陷,本人类设计基础也是初学者水平,在了解到类与类之间的多种关系后,发现该代码类间关系过于简单,这也是出错较多的原由,后续应当将类联系起来。
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
总结:
首先在第一阶段的学习中,通过循序渐进的方式从开始认识Java再到本阶段的最高潮---类设计。学习的东西虽然基础,但是掌握却需要大量联系。从最基本的语法认知,到主动自己上网查找所需要功能的写法,再到初入Java面向对象编程的基本---类设计,这带给我们的是从以前C语言编程到Java语言编程习惯的改变。作为初学者,发现还有许多东西需要去掌握:
1.类与类之间的关系,当能够了解,并运用类与类之间的关系,则能解决大多数问题,许多时候正是不知如何进行将类互相呼应,导致代码亢长,产生垃圾代码,这不利于学习;
2.正则表达式,许多问题围绕着对于字符串的处理,若用常规方法,则是耗时巨大,效率极低的,正则表达式的使用则会将问题简化,将字符串处理模式化;
3.List以及迭代器的学习,通过老师提到的迭代器功能,在演示中发现它的优越性,可以大大提高代码效率,值得我们去学习;
4.基础语法的巩固,在进行Java编程中,时常脱离不出C语言的习惯,导致出现语法错误,甚至不记得如何进行编写,这需要在练习中,不要只会对之前自己写的代码复制粘贴,还要留意写法。
感谢OOP课程老师的指导与作业监督,虽然过程很累,但还是得向前看,迎接第二阶段的学习。