一、程序结构
第一次作业:
Main: 将输入的处理都放在了Main中(不太好),包括大正则匹配整个字符串,去除多余空格。
Poly:多项式,由Item构成,实现了求导的功能。但具体项的求导没有在Item中实现,也就是Poly中取出一个项后获取其系数指数求导(不太好)。
Item:项,只重写了toSting()。其实还应该实现derivate()。
第二次作业
Main:程序入口
InputHandler:负责输入,返回得到的string。同时做了大正则的匹配(不太好),去除了空白字符。
Regex:存储各种正则表达式
Factor:接口,有toString()和derivate()方法
Poly:由若干Item构成。
Item:由若干因子构成。
Power:具体因子——幂函数
Trigo:具体因子——三角函数
第三次作业
在第二次作业的基础上增加了NestFactor(嵌套因子)和PolyFactor(多项式因子),它们中都包含一个多项式。
但是用大正则匹配和正则的递归没有成功,需要用递归下降逐层分解,使用小正则局部匹配,生成多项式->项->因子
二、程序bug分析
不佳的结构设计会影响程序的可扩展性,可维护性,不佳的实现方式往往会导致bug的出现。比如本单元出现的最大的问题是大正则。
第一次作业
String r = "((( | )*)[+-]?(( | )*)(([+-]?[0-9]+)|(([+-]?[0-9]+(( | )*)\*)|[+-]?)(( | )*)x(( | )*)(\^(( | )*)([+-]?[0-9]+))?)((( | )*)[+-](( | )*)(([+-]?[0-9]+)|(([+-]?[0-9]+(( | )*)\*)|[+-]?)(( | )*)x(( | )*)(\^(( | )*)([+-]?[0-9]+))?))*(( | )*))+";
第二次作业
1 private String signednum = "((\s*)[+-]?[0-9]+(\s*))"; 2 private String power = "(\s*x(\s*\^\s*" + signednum + ")?\s*)"; 3 private String trigo = "(\s*(sin|cos)\s*\(\s*x\s*\)\s*(\^" 4 + signednum + ")?\s*)"; 5 private String factor = "(" + power + "|" + trigo + "|" + signednum + ")"; 6 7 private String item1 = "((\s*[+-]?\s*[+-]?" + factor 8 + "(\*" + factor + ")*\s*))"; 9 private String item2 = "((\s*[+-]\s*[+-]?" + factor 10 + "(\*" + factor + ")*\s*))"; 11 private String item3 = "((\s*[+-]?" + factor 12 + "(\*" + factor + ")*\s*))"; 13 14 private String poly = "(\s*[+-]?" + item3 + "" + item2 + "*\s*)";
第一次作业只有一个大正则。第二次作业用一个Regex类来存储所有的正则表达式,稍微提高了一点可读性。第一次作业和第二次作业,都是通过一个正则表达式企图匹配整个表达式,复杂的逻辑导致正则表达式巨长,难以阅读,更不用说维护了。用一个正则匹配整个表达式,当表达式过长时,就会出现爆栈。而且此方法对于第三次作业无效,只得对程序进行大规模改动。
三、发现他人bug
我没有细读他人的代码,而是采用了黑盒测试的方法,直接通过设计样例来对所有人的程序进行测试,然后比对。为了方便,采用了自动化的方法,编写脚本实现了简易的同步测试。
关键命令:
#生成可执行文件 jar cvf archer.jar *.class #重定向实现测试及结果输出 echo %1 | java -jar ./bin/a.jar >> result.txt