第一次博客作业
三次作业小结
- 第一次作业:简单多项式的构造和求导。【正则表达式】【利用容器惰性化简】
- 第二次作业:含三角函数因子的复杂多项式的构造、求导和化简。【接口】【项抽象】
- 第三次作业:含嵌套因子的复杂式的构造、求导和化简。【接口】【递归】
第一次作业
功能介绍
对多项式进行parsing,计算导数并输出。
多项式形如
[+|-]?[0-9]*(\\*)?x(\\^[+|-]?[0-9]+)?
类图
第一次作业程序结构很简单,在单项式对象Monomial的基础上,对多项式Poly进行处理。
代码分析
可知formatCheck复杂度较高,其原因是在parsing过程中,对每个单项式均会使用check方法。
另外除了单项式toString,以及多项式构造函数setPoly外,复杂度均不高。
这两个方法较多的用了面向过程思想,在第二次作业中有较大改进,在此暂且不表。
测试与BUG
公测
公测因为formatCheck方法中正则失误,导致错误,后经修改一次AC。
互测
笔者在第一次互测中出现了大量的WF错误,程序鲁棒性较差。究其原因,是因为笔者在第一次设计时因为数字求导为0而放弃了数字的输入处理(即遇到数字则跳过),导致涉及到纯数字输入(或无合规多项式)时会输出0,导致大量错误。
Bug分析与总结
以下为笔者在第一次作业互测中发现的BUG,
选取了房间内未被找到BUG同学的代码阅读,并没有找到他的BUG。
输入时可能没有下一行,需要用Scanner.hasNextLine()判断
'\s'匹配所有的空白符,而指导书中空白符的定义只有空格和Tab
正则表达式爆栈可能性
第二次作业
功能介绍
对含有sin(x)幂 cos(x)幂,以及x幂的多项式parsing并求导,按原格式输出。
类图
第二次作业的代码结构复杂了很多,
RegDeal对字符串进行处理得到Combination。Combination是sin/cos/num/monomial类的集合,即对该题项的抽象。
对于基本类型建立抽象Part,并分别implement得到cos sin monomial类。
Combination具有求导方法,返回combination数组。(这里借助这道题项的固定格式取巧,导致第三次作业重构)
继续使用FormatCheck类对程序鲁棒性进行处理。
代码分析
可以看到FormatCheck的复杂度仍然很高,这是笔者前三次设计的败笔,为了提高程序鲁棒性而专门设计类对串进行排错。
另外不出意外的是RegexDeal.find / RegexDeal.typeJudge / RegexDeal.getType 以及Regex.main方法复杂度较高,下面逐一分析。
find/typeJudge/getType都是因为在parsing中,涉及到多次大量循环调用。
main方法复杂度高是因为将化简代码写入main中,而未在类内部进行简化处理。
测试与Bug
公测
笔者公测因为优化失误导致BUG,后一次修改AC
互测
互测中,笔者仍因为化简失误导致了较多BUG,但大部分经过修改得到解决。
仍有一些鲁棒性问题,因为笔者使用FormatCheck暴力处理。
Bug分析与总结
第二次互测,笔者学习了使用对拍器对待测代码进行处理。
- 互测中笔者根据自己的BUG修改数据,发现同屋同学在建立项时出了同样的问题,即在建立减法项时,未对项内部系数进行处理。举个简单的例子,x-x,得到错误答案2。
另外笔者根据正则表达式生成器测试了一些复杂数据,但对这类正则生成的数据,由于大多数人是使用类似的正则式处理,所以并没有太大收益。
第三次作业
功能介绍
对含有嵌套的复杂表达式parsing并进行求导,按相同格式输出。
在乘除基础上添加了嵌套运算。
类图
延续第二次作业对基础元素的设计构造,听取指导书中助教建议,使用Element接口,并对加减乘除以及嵌套模式进行抽象,得到四个运算类。
最终对字符串进行递归分析,建立项。
代码分析
由于使用递归,使得InputHandler与StringHandler的复杂度较高,另外还是使用了FormatCheck对鲁棒性进行分析。
测试与Bug
公测
由于对括号递归的不正确性,导致错误。
互测
很遗憾,笔者此次因为递归问题未能进入互测阶段。
Bug分析与总结
由于未进入互测,仅做一些思考(只有自身实际经历。
此次由于大部分使用递归,且未进行优化,bug查找显得更加困难,重点应放在鲁棒性以及括号嵌套处理上
Applying Creational Pattern
从第一次到第三次作业,笔者对抽象、接口、继承、多态的应用更加熟练,但相关设计方法如工厂方法由于接触过少,并没有实际运用于作业中,此后会选择性查看更多相关资料并应用于设计中。