一、基于度量分析自己的程序结构
(1)Project1.1
毕竟是第一次的作业,总的来说挺简单的,类图也看上去一目了然,甚至我还有心思判断数据是不是可以用int而不是Bigintenger,从而节省空间,从后面的内容看来,这没必要。
接下来是类表和方法表,与后面的相比,写起来比较*,没有很多面向对象的思想,多项式类中有一个项类的容器,并且承担了大部分工作,包括生成对象,求导,字符串化等,故复杂度较高,改进时应对多项式类尝试“减负”。
(2)Project1.2
这次的类图相比上次就略显复杂了,但主要增加的是类中的属性(两个三角函数)和方法,本次各类分工明确,结构明晰,难度个人认为较为简单。
下面是类表和方法表,可以看到,红色部分发生在解析输入、化简、字符化等处,个人认为除非将一个化简操作分为几个方法进行,否则,在解析时,结构化程度不佳,字符化时,循环复杂度也将居高不下。然后就是1.1的遗留问题,多项式类承担的任务仍然较多,这是因为除了其他类的生成,字符化等操作,还多出了求导操作以及求导后合并的操作。
(3)Project1.3
本次作业个人认为较难,而且和前两次相比难度是质的飞跃。前两次判断格式、解析输入都可以用正则表达式只手遮天,但这次由于因子嵌套,无论如何绕不开递归,而递归相比一般的循环、判断来说,难度不是一个级别。再加上对如此复杂的式子进行求导操作,再字符化输出,可以说是极其困难。类图极其繁琐,隐去了部分。
本次的特点是开始用了抽象类(Factor)和简单工厂(FactorFactory),下面是类表和方法表。
二、分析自己的bug
(1)Project1.1
无,同屋人果然也无。
(2)Project1.2
大意了,贪性能分把x**2换成x*x忘记了x**20等情况,删掉即修好。重点是没有使用自动测试,手动思考测试点过于慢。
(3)Project1.3
使用了自动测试10万次无bug才提交,结果败给了超时,自动生成的数据具有一般性,程序具有很多bug时可以很轻松的找出,但很难照顾到临界情况,对于多重括号,我的程序没有先化简再生成多项式,过多的嵌套导致程序性能指数级下降,最终TLE。
三、发现别人bug的策略
自动测试机启动,10万次,跑就完了。(而且还同时构造极端情况往里手动输,我就是狠人,隔壁zly才是狼灭)
四、应用对象创建模式来重构
工厂模式用起来确实好用,对于这次Project1.3,有很多种因子,不妨创建一个因子类,想要生成一个因子的时候,直接丢进工厂就好了,当然这也有利有弊:工厂模式要求程序员在一开始就对输入数据的形式结构有很好的处理,否则工厂很可能就是bug厂(血的教训)。工厂模式配合抽象类使用,可以大大减少类的判断、类的转换等繁琐操作,要使用的条件也并不简单:许多类具有相似的功能、属性、方法才可以使用这种模式,否则......(有什么可否则的,明摆着不一样的东西谁会把它们分成一类)
五、对比和心得体会
阅读过几位大佬的程序代码后发现,有的大佬的化简方法,我想不到[捂脸],有些大佬要么是思考良久,要么一定是*ava了,对程序的设计十分明晰,可以看出他写程序时头脑保持着高度清醒,就是在照着菜谱烧菜一样,顺理成章。此外,我还看到讨论区里使用有限状态机解析数据的大佬,并且拜读了代码,几百行的自动机学不来[捂脸],但这也给了我一种启示,其实正则虽好用,但过于模式化,在处理实际问题时,有时就会不如状态机这样精准。
在互测环节,我debug时发现我的roommate过于友好,只使用连续的括号hack,如((((((x))))))这样的至多29重括号,而不是我使用的-(-(x))型,那么就很简单被我5行内修复,(因为输出化简函数同样有化简连续括号的功能),若要使用-(-(x))型或者x+(x+(x))以及sin((x+sin((x))))型又该如何使得式子生成的多项式复杂度和实际复杂度相当呢?个人觉得,若要赶在生成多项式前就降低式子复杂度,只有可能在于输入时化简,为此我又通宵写了类似的Project1.3,在重写时明显感觉比上次顺畅,一部分是因为这是第二遍,另外很大的一部分还是在于每个类开始写时就对它自己和与他相关的类的数据生成,合并,简化,字符化都在做着准备,同时在最一开始的化简时便对各项做下标记,第一次这么呕(chu)心(xin)沥(ji)血(lv)地设(yu)计(mou)写下来,简单的几次调试便完成了debug,虽没有大佬那样的化简,但绝对没有冗余括号、符号和指数,完成后自动测试了1万次目前还没有bug,极端情况进行过许多尝试也未发现bug,这更让我体会到总体性设计的重要性。
总之第一单元完美结束了,虽然有许多小失误,但总的来说无伤大雅,也有了许多收获,比如工厂模式、千行以上代码尝试、频繁的递归等都带来了知识与能力的提升吧,期待OO继续的学习!
图为AnotherTry的方法复杂度表,可见平均值略微下降(好吧真的是略微......0.2,0.01,0.03)
将来会持续思考化简方法并推至github......
(------------------完工------------------)