OO第一单元总结

一、程序结构

第一次作业

第一次作业比较简单, 只有幂函数的求导,且不要求对WF进行判断。因此我就只用了一个MainClass类,用HashMap来存幂函数,以系数作为key,指数作为value,最后直接输出每一项的求导结果即可。整个优化也比较容易,遇到系数为1时,不输出系数;系数为-1时,只输出-;指数为1时,不输出指数,最后对项进行排序,正项先输出。比较可惜的是,本次作业没有考虑到扩展性,其实写的还是面向过程,导致后面的作业就需要重构。

UML图
OO第一单元总结_第1张图片

第二次作业

本次作业引入了新的项:三角函数和常数因子,同时三角函数和幂函数也有了线性或乘积组合。也运用了(f(x)*g(x))'=f'(x)g(x)+g'(x)f(x)的求导法则。这次我依旧选择了用HashMap来存,新增了Poly、Term、Index三个类。其中Poly类用于把字符串转换成幂函数或三角函数,Term类是用于存储形如e*x**a*sin(x)**b*cos(x)**c的式子,其中add(Poly)是完成了将各个因子相乘的操作。Index类是专门存表达式指数的,将Index作为key,将Term类的系数e作为value,可以把整个式子存入到HashMap中,需要把HashMap的euqals和hashcode进行重写。存完以后,根据sin2(x)+cos2(x)=1的性质,对HashMap中可合并的项进行了递归合并,最后优化的效果比较好,比我直接手算求导算的还对。

UML图
OO第一单元总结_第2张图片

规模度量与风格探测结果如下

OO第一单元总结_第3张图片

度量分析

OO第一单元总结_第4张图片 OO第一单元总结_第5张图片

在这次作业中,抽象做的不是很好,在正则匹配、输入输出和优化都在MainClass里完成,导致耦合度过高,设计的比较失败。

第三次作业

本次作业要求使用抽象层次(继承或接口实现)建立不同类型项之间的层次管理,同时能够进行归一化处理。在本次作业中,在线性组合和乘积组合的基础上,新增了嵌套的组合f(h(x))。我的思路是分别把三角函数、幂函数、表达式因子分别用一类进行表示,同时创建了Index接口,原程序是有diff和print两个函数,在修复bug的时候发现,其实一遍递归就可以把Index的print和diff结果求出来以后存起来。Exp类是表达式因子类,我把输入的字符串默认为Exp类,在Exp类中有一个ArrayList,通过简单的字符串处理,可以将EXP类中的各个相加减的因子提取出来,将得到的因子new Factor存到ArrayList里面。Factor类里面存的是相乘的因子,通过split分割出来,Factor类里面有一个ArrayList,用于存储每个因子,包括Tri类、Term类、Exp类。其中Term类是第二次作业中的方法,存的是形如e*x**a*sin(x)**b*cos(x)**c的因子;Tri类是形如sin(<因子>)、cos(<因子>),里面的因子用Exp类存储,如此下去,形成递归。每个类都有自己的求导法则,其中Exp类是将factor[i]的求导结果加起来、Tri类是先对外层sin->cos,cos->-1*sin,再乘上内层因子的求导结果、Term类是同第二次作业一样的求导方式、Factor类是需要遍历整个ArrayList,根据(fgh)'=f'gh+fg'h+fgh'的求导方法,将每一项求导结果与其他项相乘再加起来得到求导结果。

UML
OO第一单元总结_第6张图片

规模度量与风格探测结果如下

OO第一单元总结_第7张图片

度量分析

OO第一单元总结_第8张图片 OO第一单元总结_第9张图片

通过度量分析,第三次作业虽然做了抽象,但是每个表达式类的求导和化简需要有大量的循环和判断,导致复杂度陡增,没有做到低耦合的思想。

二、Bug分析

在第一次作业中,通过了全部中测和强测,也没有被hack到,同时性能分也都得到了,十分的幸运。在互测的时候,自己搭了评测机,检查出来屋内其他两个人在-x**-1时会少输出+的问题,但是评测机生成的数据都过于平常,能hack到人的几率不如直接用极端数据大。

在第二次作业中,强测有一个TLE,一个WA,TLE的主要原因是我的程序判断WF时根据正则表达式匹配while(m.find()),导致时间过长,改成直接判断有没有非法字符会来得快很多。还有一个Bug是在写合并同类项时代码复制粘贴的时候,粘贴完忘改i、j了,甚至本来不需要复制也可以的,结果为了怕超时反而把自己坑了。互测也是对着这个点狙,hack到别人的点也是因为合并同类项的时候存在问题。

在第三次作业中,强测依旧存在TLE的情况,同时也WA的“千奇百怪”,但罪魁祸首还是优化。比Factor类里面的print是把里面每个Index的print取出来然后乘起来,每一个print都是最简的因此可以优化掉很多多余的括号,这样看似精妙的想法,在我忘了输出乘号面前变得不值一提。还有在三角函数print函数时,也是为了优化括号,导致输出的时候少了一层括号。TLE的问题再上文提到过 ,是由于两次递归,在课下也没有测试充分,导致忽略了时间的限制。互测的时候看到了许多大佬的优秀代码,在保证正确性的同时,把化简做到了极致,但也有和我一样在多层嵌套的时候超时的同学,以及优化括号的时候少括号的,还有对首项带负号的处理的问题。

在这三次互测中,我首先是用自己搭的评测机,然后是用我在测试自己程序的时候用到的数据进行测试,最后就是一些边缘性、特殊性的数据。

三、应用对象创建模式来重构

每次作业的可拓展性都不是很好,第二次和第三次作业都经历了重构。但是也不是就完全重头再来,上一阶段的代码都可以应用到这次作业中,第三次作业开始有了点面向对象的样子了。希望以后多给自己留点余地,多点可扩展性,少点重构。

四、心得体会

从Pre作业发布到现在已经有一个多月的时间了,在这短时间里首先是感受到了我自己代码水平的突飞猛进,从2月份第一次接触Java到现在第三次作业1k行的代码量,但是还是存在很多问题的。其实每次重构前想得都差不多了大体上是没啥问题的,但在具体很多细节上做的就很不好,经常少个这、忘个那的,真的太伤了,在以后的单元作业中一定要杜绝这样的小毛病。还有就是,虽然这一个单元的任务顺利的完成下来了,但对于面向对象的理解和体会还不够,感觉更多的还是我那顽固的面向过程的思想,还得在以后的作业中多加练习。

你可能感兴趣的:(OO第一单元总结)