BUAA OO Unit1
第一次作业:
作业要求:完成多层嵌套表达式和函数调用的括号展开与化简
思路:
由于该次作业所有参与运算的部分均可以写成多项式的形式,因此可以将所有的式子都写为多项式系数+指数的形式。
那么因子、项、表达式都可以通过一个多项式类继承过来。
然后就是符号和空格
我通过正则表达式和替换的方法将所有的符号都化成了只有一个的形式,并删去了所有没有作用的空格,最终只需要将顶层表达式的多项式化简即可
结构采用了training中使用的递归下降的文法分析,层次也比较清晰明了
UML图:
结构分析:
CogC
= Cognitive complexity
(认知复杂度)
ev(G)
= Essential cyclomatic complexity
(基本圈复杂度)
iv(G)
= Design complexity
(设计复杂度)
v(G)
= cyclonmatic complexity
(圈复杂度)
可以看出第一次作业虽然正确性和性能没有问题,但是它写的不是很oo(
没有低耦合高聚合的性质,圈复杂度也相对较高,这一定程度上导致了我第二次作业的重构(
第二次作业:
作业要求:通过对表达式结构进行建模,完成多项式的括号展开与函数调用、化简,进一步体会层次化设计的思想。
思路:
第二次作业开始加入了三角函数,导致我原来只使用多项式存储的方法不能很好的适应新的版本,于是我就重构了(
又考虑到了同类项可以合并,于是使用了hashMap作为容器,以表达式为key,系数为value的形式,就能很好的完成同类项合并的工作
自定义函数的处理我使用了replace的方式,在预处理中将自定义函数替换成等价的多项式,使得解析层面的改动不用太大
总体还是采用递归下降的解析,然后处理一下不同类别的乘法和加法。
UML图:
结构分析:
CogC
= Cognitive complexity
(认知复杂度)
ev(G)
= Essential cyclomatic complexity
(基本圈复杂度)
iv(G)
= Design complexity
(设计复杂度)
v(G)
= cyclonmatic complexity
(圈复杂度)
在ParseFactor的时候将所有的Factor都写进了if-else结构中
在ReplaceString的时候将x,y,z的部分也都写进了if-else结构
导致了最终的CogC和V(G)略高,但确实就是喜欢写if-else
遇到的Bug:
1.强测的时候一开始替换符号阶段的---和+++出现了问题,在互测阶段的被一顿爆杀
2.在调试的时候,一开始没有重写hashmap的key类的hashcode和equals方法导致一直无法合并同类项,利用object类中自带函数的即可
3.浅拷贝和深克隆,在hashmap使用entry取值做乘法时被折磨了很久,贴一篇讨论区的讨论:什么是可变对象和不可变对象?什么是浅克隆什么是深克隆? - 第二次作业 - 2022面向对象设计与构造 | 面向对象设计与构造 (buaa.edu.cn),里面的讨论讲的很清楚了,不过多赘述
小结:
相比较于改屎山还是重构比较香
第三次作业:
作业要求:通过对表达式结构进行建模,完成多层嵌套表达式和函数调用的括号展开与化简,进一步体会层次化设计的思想。
思路:
这次作业中需要进行多层的嵌套以及自定义函数的嵌套,因此单纯的字符串替换已经不能解决问题了,但是我又不想改大的架构(不想重构了qwq
因此我考虑模仿parser中的递归解析,首先递归的将所有的自定义函数替换了
然后感觉剩下的部分也没有和第二次差多少,大概就是会在sin和cos内部继续递归下去,在因子层面稍微进行改动就可以了,将arraylist替换成了hashmap方便合并同类项以及做三角函数优化
UML图:
结构分析:
CogC
= Cognitive complexity
(认知复杂度)
ev(G)
= Essential cyclomatic complexity
(基本圈复杂度)
iv(G)
= Design complexity
(设计复杂度)
v(G)
= cyclonmatic complexity
(圈复杂度)
在因子层面继续细分了之后,使得在parseFactor的时候的结构清晰了一些
然后对拍的时候也没有拍出什么问题,但是被丧心病狂的互测爆杀
遇到的Bug:
1.sum里面的l和r可以是Biginteger,我根本没有考虑到这方面的内容,甚至造数据的时候也直接是int内,直接被橄榄
总结:
感觉这三次作业还是挺人性化,没有想象中那么难,只是因为我单纯的有点懒没有做多少优化,因此失去了不少的性能分。
另外一个很重要的感受就是要多看讨论区、多和同学交流。讨论区中有很多有意义的帖子,能解决完善代码时的不少问题。在觉得方法有些复杂的时候可以多和别人多沟通,多了解一些想法,这样可以避免思维狭隘,能够更加清晰理性的看待问题。
TIPS:
1.优化和正确性解耦
包括我在内的许多同学都遇到了进行优化的时候失去了正确性。为了解决这个问题,优化的过程应该正确的解析过程分开,这样不管是在调试错误,还是在后期测试的时候,都比较方便找到问题所在
2.随机测试覆盖的重要性
这几次出现bug都是由于测试的时候没有完全覆盖导致的,在听了何天然同学的分享后,学习到了可以依照形式化表达的方式写构造函数来生成数据,这样就能比较好的覆盖
还有就是特殊数据的处理,我一开始没有处理0的问题,一直输出空串,直到最后才恰好跑出一组我没有输出的数据才发现了问题所在
特殊数据的构造一定要心狠手辣
3.不要偷懒!
偷懒一时爽,强测互测火葬场。年纪轻轻不要天天开摆,更不要相信别人开摆