BUAA-OO-Unit1单元总结
第一次作业
1、代码结构分析
表达式解析第一次作业中只需要对无嵌套括号进行拆解,将同类项进行合并。我的思路是利用递归下降法将表达式向下拆解成一个树,
在从下向上将各因子进行组合,然后进行同类项的合并。类图如下:
Dispose类中的removeSymbols()用来处理空白符和连续的正负号,removePower()用来将乘方拆解成多个因子相乘,combine()用来合并同类项。
Lexer类和Parser类用来解析Dispose处理后字符串。
Expr类表达式级,存储项Term。
Term类项级,存储因子Divisor。
Divisor类因子级,存储常数因子和x。
Expr类、Term类、Divisor类的toString()方法将本级表达式计算之后传递给上一层。
2、代码度量分析
从上图中数据可见,总体的代码复杂度不是很高,除了combine()合并同类项时需要用到较多if来判断特例0、+1、-1、2(毕竟x*x比x**2少一个字符)和边界情况,
递归下降法能很好的将复杂的表达式进行解析,来降低总体代码的复杂度。
3、Bug与Hack
在第一次作业中,我出现了一个bug,是在Dispose类中的removePower()中使用正则表达式的通配符"."导致匹配的范围过大导致,修复时只需要将"."变为[0-9x*+-]即可。
在hack别人时,也发现房间中有几个人有和我类似的问题,都是用"."导致的匹配范围过大出错。
还有在表达式结果为0时无输出的现象,应该是没在结尾判断解析的结果(res!=null),导致无结果输出。
第二次作业、第三次作业
1、代码结构分析
由于第三次作业在内容上仅增加了嵌套和一些细微的处理,所以第三次的代码在第二次作业的基础上进行了一些调整,在结构上并没有什么改变,故将以第三次作业进行第二次和第三次作业的分析。
第二次作业相较于第一次作业作业增加了三角函数、自定义函数、求和函数,所以我的结构上进行了一些改变。
在顶层,修改了removePower(),这次的表达式复杂程度明显增加,又有上次正则表达式的教训,所以这次将正则表达式变为了字符解析来去除乘方。同时,Lexer类中加入了getFunc()用来获得这三大函数因子,并使用了枚举类进行区分。
在底层(Factor级)增加了TrigFunc、SelfFunc、SunFunc这三个类用来存储这三角函数、自定义函数、求和函数,同时在向上返回时对自定义函数和求和函数进行求解,求解后的表达式后再次调用递归下降处理。
第三次作业增加了嵌套,而在进行第二次作业时就已经能够处理自定义函数和求和函数的嵌套,第三次作业仅对三角函数进行了可嵌套处理,同时对一些地方进行了细微的调整。
第三次作业类图如下:
2、代码度量分析
总计写了三十多个函数,其中有四五个函数的CogC、iv(D)、v(G)被标红,仔细查看发现这些函数都与表达式的合并有很大的关联,
在合并的过程中需要用到很多的循环和判断,导致代码的复杂度很高。
上图为内聚耦合情况分析图,图中标红的还是很多的,总体代码的耦合度挺高的,类与类之间的关系较为复杂,写代码的时候为了减少类就在通过
一个类中定义了较多的功能完全不同的方法,是代码的内聚性较低,这也是以后需要改正的地方。
3、Bug与Hack
在第二次作业和第三次作业中各出现了一个bug。第二次出现的bug是由于失误导致的,在化简sin(0)时,应该向HashMap的key中放入字符串"1"(1代表常数),
却错误的放入了字符串"0",对于出现这样的不应该的bug,我很痛心。第三次出现的bug是对形式化表达的理解不够,
我个人认为sin(-x)是合法的,没想到-x是个表达式,必须要再加一层括号,即sin((-x))才是合法的。
在第二次作业中,我贡献了全房间的成功率(只有我被hack),没有发现房间中的其他人的bug。在第三次作业中,有三个人用int型变量接求和函数的上限和下限,导致解析出现bug。
Bug分析与Hack策略
1、Bug分析
纵观这三次出现的bug,有因为对java的理解不足出现的bug,也有自己的大意出现的bug,也有对形式化表达的理解不足出现的bug。
这也是下次应该多加注意的地方,尽量不要再次出现因自己的失误和对题目的理解不足而出现的bug。
2、hack策略
首先纵观代码,寻找代码的薄弱点(一般为应用循环或判断的地方),然后针对薄弱点进行针对性捏造数据。
或者,针对题目中容易出现问题的地方针对性捏造数据,比如第三次作业的sum的上下限问题。
心得体会
对于这三次作业,毫无疑问最大的收获就是对面向对象的理解加深了,对程序的结构有了更加深刻的理解,也明白了结构化对后续的迭代开发的帮助。
同时,在写代码的过程中有意识的开始应用“高内聚,低耦合”的设计思路,虽然现在做的还不好,但我以后一定会改进的。
同时,还有一点体会是权衡。优化或许可以得到更高的分数,但相应的会出现代码量的增加和出bug的概率增大。后两次作业就是为了优化出现了bug导致强测出现了bug,反而得不偿失。