第一单元总结

第一单元总结

在这个单元的作业主要任务是化简表达式,拆开括号并化简。

 

第一次作业

基本思路

    本次作业中我参考了训练中递归下降的方法,用Lexer类来读取字符,用Parser类来解析并存储表达式的各个部分。我在第一次作业中把表达式分为Expr、Term、Variable三个层次,每个层次实现了一个use方法来递归化简,最终将结果转化成一个存储Variable的HashMap,这样可以处理多层括号的情况,方便扩展。

    对于核心的use方法来说,Expr中的use处理好其中每个Term,将处理好的Term储存在一起;Term中的use主要完成了核心的去括号过程,对于幂函数,我将n次幂拆成了n个相乘的形式,之后用multipy方法将每个Factor相乘的结果计算出来,最终将Term转化为Variable相加;而Variable的use则是返回他本身。于是对最顶层的Expr调用use方法就可以得到化简之后的表达式。

 

代码分析

    体量分析

Source File Total Lines Source Code Lines Source Code Lines [%]
Expr.java 107 94 0.8785046728971962
Factor.java 11 7 0.6363636363636364
Lexer.java 70 64 0.9142857142857143
MainClass.java 16 13 0.8125
Parser.java 128 117 0.9140625
Term.java 83 70 0.8433734939759037
Variable.java 39 31 0.7948717948717948

 

    度量分析(标红的部分)

method CogC ev(G) iv(G) v(G)
expr.Expr.toString() 40.0 2.0 20.0 21.0
Lexer.Lexer(String) 20.0 6.0 7.0 8.0
expr.Term.use() 19.0 3.0 13.0 13.0
Parser.parseFactor() 5.0 5.0 5.0 5.0

    在Lexer和parseFactor中,我使用了很多if-else导致复杂度较高;而剩下两个部分则是因为化简导致复杂度较高

    

    UML类图

     架构整体来说比较清晰,具有一定的可扩展性

 

    bug分析

    在处理幂函数的时候有一个笔误,导致0次方有时候会出问题;同时在此次作业中未能发现别人的bug。

 

第二次作业

基本思路

    本次作业加入了三角函数,自定义函数和求和函数。对于自定义函数,我在一开始将其储存起来,使用时先在Func类里解析出形参和实参,之后将实参代入函数表达式,使用Lexer和Parser对新字符串解析,返回一个Expr。对于求和函数,也采取类似的方法进行处理。对于三角函数,我将基础结构由Variable改为Variable*Πsin()*Πcos()的形式,之后修改了Term类中的multiply方法,基本上就能实现三角函数的基础化简。

 

代码分析

    体量分析

Source File Total Lines Source Code Lines Source Code Lines [%]
Expr.java 144 129 0.8958333333333334
Factor.java 14 9 0.6428571428571429
Func.java 44 39 0.8863636363636364
Lexer.java 79 73 0.9240506329113924
MainClass.java 27 21 0.7777777777777778
Parser.java 308 292 0.948051948051948
Sum.java 60 51 0.85
Term.java 115 102 0.8869565217391304
Tri.java 127 115 0.905511811023622
VarAndTri.java 95 78 0.8210526315789474
Variable.java 72 61 0.8472222222222222

    可以看出Parser类的行数过多,这是因为此次作业中这部分重复的代码过多,可以进行优化。

 

    度量分析(标红部分)

method CogC ev(G) iv(G) v(G)
expr.Term.mult(ArrayList, ArrayList) 27.0 1.0 8.0 9.0
expr.Expr.print() 24.0 4.0 11.0 13.0
expr.Tri.sSin() 22.0 1.0 10.0 10.0
expr.Variable.toString() 21.0 1.0 11.0 11.0
Lexer.Lexer(String) 20.0 6.0 7.0 8.0
expr.Term.use() 19.0 3.0 13.0 13.0
expr.Tri.sCos() 19.0 1.0 9.0 9.0
Parser.getCos() 17.0 1.0 9.0 9.0
Parser.getSin() 17.0 1.0 9.0 9.0
Lexer.next() 15.0 2.0 14.0 19.0
Parser.parseFactor() 10.0 9.0 11.0 11.0

    这次作业我的程序复杂度较高,一方面是由于加入了新内容,导致读入解析、化简时的复杂度上升;另一方面,我代码中有一些重复的地方,同时三角函数内部的处理完成得不是很好,导致出现了一些bug。

 

    UML类图

 

 

 

    bug分析

    这次作业中我在强测中就出现了好几个bug。第一个是在三角函数内没有考虑带符号的情况,主要是由于没有在测试前做足够的测试。第二个是深克隆的问题,在对一个因子进行处理时会影响其他的项,我在测试时发现了这个问题但是在截至时间之前没有想出原因。第三个是没有将sin(0)**0设为1。

    由于我这次作业完成得不好,所以被分到了C房,输入一些比较基础的数据就能找到别人的bug。例如在sin(-x),有好几位同学都和我一样没有考虑这方面的问题。

 

第三次作业

基本思路

    这次作业主要要求实现函数的嵌套、三角函数的嵌套还有多层括号的嵌套,大部分内容在之前的作业中已经可以实现,因此没有做太多修改。这次作业主要修改了三角函数内的部分,之前使用Variable存储,现在采用String存储,这样能够存储更多内容,而解析方式也改成了读入字符串用Lexer和Parser解析。

 

代码分析

    体量分析

Source File Total Lines Source Code Lines Source Code Lines [%]
Expr.java 171 160 0.935672514619883
Factor.java 14 9 0.6428571428571429
Func.java 57 50 0.8771929824561403
Lexer.java 79 73 0.9240506329113924
MainClass.java 27 21 0.7777777777777778
Parser.java 249 233 0.9357429718875502
Sum.java 63 54 0.8571428571428571
Term.java 114 101 0.8859649122807017
Tri.java 114 103 0.9035087719298246
VarAndTri.java 91 75 0.8241758241758241
Variable.java 72 61 0.8472222222222222

    进行了部分优化,相比与第二次作业行数有所减少。

 

    度量分析(标红部分)

method CogC ev(G) iv(G) v(G)
expr.Expr.toString() 45.0 3.0 23.0 24.0
expr.Term.multiply(ArrayList, ArrayList) 27.0 1.0 8.0 9.0
expr.Variable.toString() 21.0 1.0 11.0 11.0
Lexer.Lexer(String) 20.0 6.0 7.0 8.0
expr.Term.use() 20.0 3.0 14.0 14.0
expr.Tri.sCos() 20.0 1.0 12.0 12.0
Lexer.next() 15.0 2.0 14.0 19.0
expr.Tri.sSin() 15.0 1.0 10.0 10.0
Parser.parseFactor() 10.0 9.0 11.0 11.0

    这次作业中我在toString中又加了一些化简内容,导致复杂度高;圈复杂度高的部分主要是由于读入输出时各种判断导致if-else语句使用过多。

    

    UML类图

 

 

     第三次作业的UML与上一次相比并无太多变化。

 

    bug分析

    这次作业我有两处bug。第一处是sum上下限未考虑范围,采用了int,导致数据过大时会报错;第二处是sum中替换i时没有加括号导致负数会出错。主要还是因为没有考虑全面而产生问题,之后应该注重测试的覆盖程度。

    hack别人时发现有一位同学在处理sin(-x)时没有加括号,可能是由于优化时没有考虑到这种情况导致出错。

 

心得体会

    这是我第一次使用面向对象的思想完成并迭代程序。这个单元的学习让我意识到好的架构的重要性,优秀的架构具有良好的可扩展性,可以让迭代优化变得比较容易。

    在这一单元的作业中,我还有许多做得不够好的地方。比如测试方面有所欠缺、优化程度不够高、没有去限制程序复杂度。在下个单元的学习中我会着重去弥补这一单元做得不够好的地方。

 

posted @ 2022-03-26 14:14  jht0725  阅读(11)  评论(1编辑  收藏  举报