oo第一单元总结
(1) 基于度量来分析自己的程序结构
方法和类的复杂度分析图片中ev(G),iv(G),v(G),OCavg,WMC含义如下:
ev(G)即Essentail Complexity,用来表示一个方法的结构化程度,范围在[1,v(G)]之间,值越大则程序的结构越“病态”,其计算过程和图的“缩点”有关。
iv(G)即Design Complexity,用来表示一个方法和他所调用的其他方法的紧密程度,范围也在[1,v(G)]之间,值越大联系越紧密。
v(G)即循环复杂度,可以理解为穷尽程序流程每一条路径所需要的试验次数。
OCavg代表类的方法的平均循环复杂度。
WMC代表类的总循环复杂度。
第一次作业
类图
方法以及类的复杂度
思路分析:第一次作业中使用了四个类。Main类负责输入表达式正确性的判断,首先是利用正则匹配,直接对表达式进行判断,后来发现出现爆栈的问题,出现爆栈的原因是因为正则的贪婪特性,之后便改为用替换的方法,先将首项替换为空字符串,再将其他项替换为空字符串,最后和空字符串比较,两者比较结果为真则输入正确;Pushtoarr类将表达式分离为项,通过ArrayList保存,再将项中系数和指数通过动态数组保存,最后进行求导并保存结果;Remove类主要是去除数的前导0,但互测时才发现这一步多余,将字符串转换为BigInteger类型不需要去除前导0;Jianhua类主要是将求导后的表达式简化,合并同类项,对指数为0,1,系数为0,1,-1的项进行优化处理。
优点:学到了正则表达式的用法,使用了四个类,虽然说还未摆脱掉c语言代码风格,但通过这次作业了解并应用了对象与类。
缺点:正则表达式过长,出现bug后难以定位。类中许多方法都使用了许多if else语句,导致代码量较多。
第二次作业
类图
方法以及类的复杂度
思路分析:第二次作业使用了五个类,Main类进行输入,输出;Judgeregex类利用正则判断表达式的正确性,改进了第一次的正则写法,写出因子的正则,然后合并为项的正则,判断正确性则是与第一次作业一样;Cutterm类通过split将项与项分离;Splitfactor类将项分割成系数,x的指数,sinx的指数,cosx的指数。Derivative类进行求导,合并和优化。
优点:将项化为了x,sinx,cosx,便于以后的求导,合并,优化,对于类中的属性,只能通过get()的方法读取,封装得较好。
缺点:未能用到同学课上介绍到的try-catch,不熟悉其用法,Derivative类中进行了求导优化化简,方法太多,代码量较多。
第三次作业
类图
方法以及类的复杂度
思路分析:此次作业写出的程序与第一次和第二次作业有了较大的区别,表达式正确性的判断并不是提前处理,而是边建树边判断,运用到了五个类,Main类进行输入输出,Wrongformat类进行预处理,提前处理一些显而易见的错误,以及将空白字符给去掉,便于以后的数据处理,Expression类属性为ArrayList,储存Term对象,Term类属性为ArrayList,储存Factor对象,Factor属性为me和ArrayList,属性me区分数,x,sin,cos,表达式因子,ArrayList存储可能存在的嵌套因子(Factor对象)或者表达式(Expression对象)。将树建立后,进行求导。
优点:学会了用try-catch机制,应用递归建树。
缺点:未能进行合并优化,未能用到接口。
(2)自己程序的bug
第二次作业:互测时发现了一个bug,未能仔细阅读题目,忽略了项与项之间可以存在三个正负号的问题,
第三次作业:强测时,输入x*+x未能输出相应结果,预处理时忽略了这一情况。
互测时,输入sin(-7)未能得出正确结果,在程序中将-+也当成了因子,所以会程序错误。
(3)发现别人程序bug所采用的策略
第一次通过爆栈,空格超时,以及阅读他人正则表达式时发现了一些bug。
第二次通过阅读正则表达式(例如缺少\t)以及表达式输出找到了bug。
第三次主要是通过设计正确的输入来找bug。
(4)Applying Creational Pattern
第三次作业建立了树的概念,若增加其他数学符号tan等,可以在原有代码上增加少量代码即可将树建立起来,但第三次作业未能实现一个求导的接口,未能描述类之间的共性行为,并且在求导时,因子与因子之间只考虑了乘法,如果增加其他的运算法则,则难以扩展,因此应该实现一个求导的接口,增强程序的可扩展性。