基于度量分析程序结构
-
UML图:主要分为三部分,主函数负责字符串接收和对项整体的处理,ExpressionPatterns负责检测正则表达式,Term为处理对象。
-
复杂度分析:所有针对项整体的处理工作都是在Main中完成的,可以考虑分解成一些更小的函数,提高可读性。转换字符串输出沿用了课上实验的思路,实际可以更简单。
本次作业没有bug,但没有做到完全优化,应该单独判断第一项是否输出符号,并去掉对±0的输出。
发现别人bug所采用的策略
总结边界条件和可能出错的点,针对性地进行测试。
例如1求导输出0,+-号处理,超过int范围的系数和指数等等。
同时也用python随机生成一些比较长的样例来测试。
应用对象创建模式来重构
本次作业构建了Term对象,
对比和心得体会
由于第一次作业思路比较直观,房间内其他同学的代码基本也都采用类似架构。
在对比中我发现我的Main函数比较复杂,可以进一步封装。
第二次作业
基于度量分析程序结构
-
UML图:整体架构仍和第一次一样,把Term扩展为形如a*x**b*sin(x)**c*cos(x)**d的项,同时增加Simplifier判断WF和化简。
-
复杂度分析:可以看到Main仍然较为复杂。differentiate的实现思路也很冗余,导致复杂度高。
bug分析
本次作业有三个bug。
(1)没有看清x指数边界条件是<=10000,将10000的情况判断为WF。
(2)在每一项中采用String的length判断x指数是否合法,导致在有前导0时出错。修复后将String转换为BigInteger判断。
(3)对于x*cos(x)**2*10001这样的项,我的做法是首先处理并删去cos(x)**2,导致生成了x**10001这样的项,判断为WF。解决方法是把匹配内容从cos(x)变成了*?cos(x)。
另外的问题就是只进行了简单的合并同类项,导致性能分很低。
发现别人bug所采用的策略
与第一次作业大致相同。
应用对象创建模式来重构
本次作业沿用了Term对象,但在其他人代码里发现用sin, cos, x三种对象也是一种很好的思路。
对比和心得体会
通过阅读互测组里的代码,我发现我使用的求导方法很不合理,原因是我仍然把x、sin和cos看成不同的三项,试图先把Term分离成三项,分别求导后再按规则乘起来。实际上只需要算出Term对x、sin(x)和cos(x)的导数即可。
同时,我写了过多的正则表达式,其中有一些写法不必要(例如我把?都写成了{0,1}),还有很多正则的中间项可以省略。
第三次作业
第三次作业没有通过本地测试。深层次的原因是前两次遗留下来的架构缺陷没有及时改善。在前两次作业我一直使用大正则,在遇到循环定义的正则时不知道怎么处理。讨论区主要提供了表达式树和小正则两种方法,但我在短时间内没能重构出合理的结构,也没能想清楚一些细节的实现。
优秀代码的结构和我的思路确实非常不同。在第三次作业,把所有正则表达式丢在一个类里的思路已经完全不适用了,要把这些正则所定义的对象分别处理。例如优秀代码里很多都采用了以factor为接口处理三角函数、项、表达式等不同factor,完成求导、clone等共性操作,以及用工厂模式进行管理的思路。
总结
这一单元暴露出了很多问题。因为前段时间的一些个人原因,没有能投入足够精力在OO课程上。每次作业开始得都很晚,也出现了非常严重的后果。在下一单元作业中一定会全力以赴。