OO第一次博客作业

时间:2022-03-11 07:48:11

OO第一次博客作业

零、写在前面

OO第一单元宣告结束,在经历了前三次周末的痛苦后,这次终于可以有所喘息了。每次都是在绝望中寻找希望,虽然结果不尽人意,自己已经得到了成长;也许这才是最重要的。

一、基于度量的分析

第一次作业

总体结构分析

OO第一次博客作业

在第一次作业中,采用的完全是之前的面向对象思维;所有类都建为了内部类,其实和C的函数(方法)无甚两样。所以说整个代码看起来并不好看。但是也算是采用了ArrayList、BigInteger和正则表达式的新方法。

复杂度分析

OO第一次博客作业

Main、Main.CoeExp和Main.Derivation复杂度十分之高。单是CoeExp一个内部类就接近60行;而且大部分是存在duplicate代码。Derivation类也是如此。如果当初想把WF分开处理、常数和x分类处理的话,不仅复杂度会大大降低,而且第二次也不至于几乎全片重构。
OO第一次博客作业

CoeExp的问题上面已经提过。还有就是judge问题,这个基本是穷举法,导致极其庞大。后面的作业有所改进。

依赖度分析

OO第一次博客作业

模块之间依赖度低。

第二次作业

总体结构分析

OO第一次博客作业

本次作业和第一次作业最大的区别是把内部类分离开来。而且WF判断虽然没有单独设类,但是拆为了三个部分进行判断。Merge合并同类项后到Term进行求导,思路清晰。但是问题是,如图所示仍存在大量duplicate代码(比如multia、b、c),仍然是不合理的地方。

复杂度分析

OO第一次博客作业

OO第一次博客作业

OO第一次博客作业

问题和第一次基本重合,还是可以分出更细的类出来,现今而言三个类每个都比较臃肿。multia、b、c复杂度完全是相同的,需要考量怎么改进(继承与接口的应用,第二次作业还不会使用)。但是大体来说,第二次作业思路是很清晰的,是采用形如kx^asin(x)^b*cos(x)^c的统一求导公式,但是问题是可扩展性非常小。后期又进行了sin(x)^2+cos(x)^2这样简单的化简,但是没有向更高次继续,原因可能是怕出错。

依赖度分析

OO第一次博客作业

和第一次情况大体相同。

第三次作业

总体结构分析

OO第一次博客作业

可以看出结构还是树形结构;整个思路Term(表达式类)和Factor(项类)进行递归求导。对于一个表达式,先去掉最外层的括号,然后创建Term类;Term类中由+分隔,创建Factor类;Factor中如果是基础项(常数、x、sin(x)、cos(x))则直接返回导数,如果是正余弦嵌套则由Dericomposite返回去掉一层嵌套的式子然后创建Term类递归求导,如果是()表达式则直接创建Term类进行递归求导。思路还算明确,但是问题是当初嵌套处理出现了相当大的问题,导致强测中一连串的REG。真的是遗憾不已。

复杂度分析

OO第一次博客作业

OO第一次博客作业

OO第一次博客作业

可以看出,复杂度相对于前两次已经有了相当的改进;但是仍然存在大量复杂。容易看出,主要是WF的判断太臃肿。因为主要采用的思想仍然是穷举。

总结

三次作业总的来说进步还是肉眼可见的(自我感觉),主要是从第一次面向过程到后面的面向对象思想的逐步建立。但问题是,事实上,每一次作业都没有在前一次的基础上进行深入,而是基本每次都在重构。原因也很容易分析,架构的相对僵化,可扩展性差,每次都是只考虑本次的问题处理而没有深入分析其共性。而且在第三次作业中刚开始仍然尝试用之前的正则表达式强行匹配,但是结果是括号问题使我碰了一鼻子灰,也浪费了大量时间。第三次作业的最终结果是不太理想的,但是在bug修复的过程中重新思考的过程又是一次提升。这大抵算一种成长吧。希望以后会越来越好。

二、bug分析

第一、二次作业事实上并没有出现什么值得讲的bug。这里主要讲一下我的惨烈的第三次作业吧。

主要就是WF判断和正余弦嵌套的问题,而这两种问题使我bug修复改了一天之久。

对于WF判断,主要出现的问题是前文提到过的去掉表达式两侧的括号创建Term类,但是单纯地掐头去尾导致了(((x+x)(cos(x)+cos(x))+(sin(x)+cos(x))(sin(cos(x)))))这样的强测样例化简后出现了x+x)(cos(x)+cos(x))+(sin(x)+cos(x))(sin(cos(x))这样的奇怪格式从而输出WF。归根结底是栈的应用没有用彻底,很多地方想偷个懒不愿意用栈(或是没考虑周全),然后就导致了程序出错。

对于正余弦嵌套的问题,也是栈操作,之前用暴力正则匹配,然后强测出来发现一堆REG。归根结底是暴力正则难以覆盖所有的情况,于是bug修复不得不采用写一个新的方法判断嵌套问题,也是栈。

可以说,强测与互测90%的bug都是栈,一切都是当初考虑不周。我本应想到括号和栈的紧密联系的;可惜了。不过这次也算是上了好好的一课,以后再出现这样庞大的漏洞的话,会自己给自己两个耳光。

三、互测策略

前两次还是在手动找bug的,到了第三次便开始使用对拍程序进行大规模AOE轰炸。其实这是好是坏我也不太能辨清,因为在用python对拍的时候完全忽略了读他人的代码而只是不停地造数据。其实我想这大概是课程组不希望的;但是这确是互测抢分的高效手段。这就是个很矛盾的问题。

P.S.其实不难发现规律是自己程序越烂的人越热衷于对别人的程序动手以挽回错失的分数,而对拍程序的大量使用使得读他人代码变得低效而不愿意这样去做。其实我想刀人越多的人越应该仔细分析自己的代码改进空间而不是通过对拍程序去搞其他人(同质使得得分效率并不高),所以建议能否增加强测修复得分?

四、Applying Creational Pattern

第一次是单例模式,第二三次是工厂模式。但是没有使用接口。