OO第一单元总结
前言
在寒假时便听闻了一些关于OO的传闻,某乎上也看了许多,但是今年由于助教和老师的努力,感觉和学长学姐口中的OO完全不一样了。虽说难度依然不小,而且的的确确也是耗费了大量的时间和精力(有时候感觉收获并不是很多,只是为了分数在挣扎),但OO的进步也是有目共睹。
第一次作业
从寒假的简单入门题突然跨越到了求导,确实还是花了一番功夫来适应。本来个人的代码能力就不是很强,这样的题哪怕是用我所熟悉一点的C语言之类的来写个面向过程的程序也是略有难度的,何况还要“假装”面向对象。
代码分析
以下是UML类图和Metrics分析



由于是第一次尝试分析,所以记录一下各个指标的含义。
在Method Metrics中可以看到ev, iv, v这三栏,分别代指基本复杂度(Essential Complexity (ev(G))、模块设计复杂度(Module Design Complexity (iv(G)))、Cyclomatic Complexity (v(G))圈复杂度。
ev(G)基本复杂度是用来衡量程序非结构化程度的,非结构成分降低了程序的质量,增加了代码的维护难度,使程序难于理解。因此,基本复杂度高意味着非结构化程度高,难以模块化和维护。实际上,消除了一个错误有时会引起其他的错误。
Iv(G)模块设计复杂度是用来衡量模块判定结构,即模块和其他模块的调用关系。软件模块设计复杂度高意味模块耦合度高,这将导致模块难于隔离、维护和复用。模块设计复杂度是从模块流程图中移去那些不包含调用子模块的判定和循环结构后得出的圈复杂度,因此模块设计复杂度不能大于圈复杂度,通常是远小于圈复杂度。
v(G)是用来衡量一个模块判定结构的复杂程度,数量上表现为独立路径的条数,即合理的预防错误所需测试的最少路径条数,圈复杂度大说明程序代码可能质量低且难于测试和维护,经验表明,程序的可能错误和高的圈复杂度有着很大关系。
Class metrics中两栏分别为Ocavg(Average Operation Complexity)和WMC(Weighed method complexity)
在main函数中,我的基本复杂度较大较大,我定义了一个output的函数方法用于输出结果,不过模块化程度还算可以。
可以看出面向过程的思路还是较为明显,main的复杂度和耦合度都比较高。主要是因为大部分内容其实都还是在main里面实现,包括输入和输出的处理,WF的判定,除了求导以外的计算过程等等。Term里面重要的方法仅仅只有求导而已。
公测
正确性满分,有少部分优化被扣分。优化了同类项合并和正项提前。
互测
-
被Hack的BUG
被Hack了7下,都是同质BUG,都是因为在正则表达式中使用了\s,然后在处理的时候使用了trim。当时其实知道\s会匹配到空格和\t以外的空白符,也知道trim会删去其他空白符,但是天真的以为其他空白符无法通过键盘输入,结果其实自己写个程序就能输出。 -
Hack别人的BUG
自己也尝试用了\v去hack别人。Room内还有一个同学在判断空格和\t的时候使用的[' '\\t],就会匹配到单引号。
发现BUG的策略主要是通过看正则表达式,因为感觉自己正确性还是不错,所以应该分到的room正确性也不会低,一般能求导成功的都会是正确的结果,所以着重看了对WF的分析的部分。
总结
第一次作业大家大部分还是面向过程的思路比较明显,我看到的几个代码中没有类超过3个的,而且感觉也是为了写新的类而写新的类,并没有深刻理解类的含义和用法。
第二次作业
第二次作业我放弃了正则表达式,选择了自己写方法来获取按照我的方式拆分好的类。完全重构了代码,使得扩展性更强。
代码分析
以下是UML类图和Metrics分析




可以看出这次作业的结构更为清晰,并且对类的理解更深入之后,有了更好的扩展性,为第三次作业打好了基础。虽然有些方法的复杂度仍然较高,但是对于我的设计而言,这是无法避免的,毕竟自己手写了输入处理而放弃了正则表达式。
之所以放弃了正则,是因为采取了读一个因子就删去一个因子的操作,为每种因子写了输入方法和合法性判断,其实也不是很难,处理起来感觉也很方便。
从一main到底到逐渐掌握设计思路,这次是从面向过程到面向对象的一个重要过渡时期。在Term函数中,基本复杂度比较大,但是考虑到Term类必须要实现的许多方法,我个人感觉做到这个程度也算可以理解。
关于优化,本次做了的优化依然有正项提前和合并同类项,但是只合并了很基础的同类项,即只有系数不相同的项,没有做更多的优化了。没有时间也没有思路,后来研讨课听了大佬的分享感觉收获很多,但是再给我一次机会我依然选择不写更多的优化,感觉有点破坏代码的设计(因为自己能写出来的优化可能都比较难看吧)……
公测
公测出现了长度非法的表达式,并且可能由于测评姬的bug我一分优化分也没有,很奇妙。rejudge之后依然是正确性满分,优化扣了一些分数,意料之中。
互测
互测第一次尝试了在虚拟机下使用命令行八个人一起跑,参考了讨论区各位大佬写的脚本之类的,写了个不太自动的多人对拍,功能也很有限,但是感觉还是比挨个看好太多了。这次互测找BUG的思路也是先看正则表达式,有的正则表达式真的错得比较明显,比如只考虑了s in(x)和si n(x)非法,如果输入s i n(x)就不会非法的情况。有自己特意造数据的,也有多人对拍的时候大量随即数据拍出来的,为了避免太多同质bug还是分析了一下错的点。互测room内有个大佬优化超级好,代码也很简洁好看,学习了一波。
像我这种没写正则的人估计大部分也都是靠造数据来hack我吧,然后好在正确性还ok,所以互测0bug。
总结
第二次作业花了很多时间来设计和重构,虽然过程很痛苦取舍了很多,但是最终还是学到很多东西,并且也在第三次感受到了“幸好我重构了不然我等死吧”的感觉。
第三次作业
第三次作业在第二次的基础上进行了扩展,其实在第二次我的求导就采用了递归下降的思路,这次加入了嵌套读取表达式并判断合法性。大部分类和方法都继续使用,在原基础加了Trifunc和Const类,便于嵌套函数的读取和处理。
代码分析





代码的复杂度和耦合度和第二次出入不大,不多详细描述。
公测
正确性满分,优化部分扣分。
互测
互测room内有个大佬优化太好了,而且正确性也很好,学习了很多。room内有的同学会发生输出空括号的情况,没有仔细看代码,但是大概是优化了指数或者系数的一些特殊情况,我猜测应该是针对特殊数据的优化,所以有些没考虑到的情况就会出错。我自己没有增加过多的优化,继续使用了上次的简单优化,更多的把注意力放在了扩展和思考架构上。
自己依然0bug。
总结
OO第一单元结束了,但我感觉自己距离OO入门还差得很远。这门课确实占用了很多时间,压力也很大,不知道能收获多少,只能说尽力而为。希望以后也能平安度过每一次作业。

浙公网安备 33010602011771号