OO-2021-buaa 第一单元
引言
第一次作业
类图

构架设计
-
MainClass类主要实现对表达式的处理,将表达式做一些简化操作,如去空格,合并符号,替换'**'等,并用split将表达式拆分成项。
-
MainTerm主要对项的处理,将项根据 ’^‘ 拆分成系数和幂指数。
-
PrintSt主要是求导和输出形式的处理。
代码复杂度分析
类复杂度
| class | OCavg | OCmax | WMC |
|---|---|---|---|
| MainClass | 8.00 | 8 | 8 |
| Mainterm | 2.00 | 5 | 8 |
| PrintSt | 7.00 | 7 | 7 |
| Total | 23 | ||
| Average | 3.83 | 6.67 | 7.67 |
方法复杂度
| method | CogC | ev(G) | iv(G) | v(G) |
|---|---|---|---|---|
| Mainterm.Mainterm(String[]) | 11 | 1 | 5 | 5 |
| Mainterm.getCoef() | 0 | 1 | 1 | 1 |
| Mainterm.getIndex() | 0 | 1 | 1 | 1 |
| Mainterm.getMap() | 0 | 1 | 1 | 1 |
| PrintSt.PrintSt(BigInteger,BigInteger) | 15 | 2 | 11 | 11 |
| MainClass.main(String[]) | 11 | 3 | 7 | 9 |
| Total | 37 | 9 | 26 | 28 |
| Average | 6.17 | 1.50 | 4.33 | 4.67 |
PrintSt下的PrintSt中,对输出形式的各种形式进行考虑,运用了多个if分支,复杂度较高。
Bug分析
第一次作业中,各个类都还算简单,结构也相对清晰,在正确性上没有出现什么bug,但是,因为没有对输出的结果进行分析,性能分相对较低。
小结
第一次作业做的时候感觉很困难,对Java极不熟悉,很多东西都是现查现做,做的时候比较艰难,耗费时间很长。
第二次作业
类图

架构设计
本次表达式求导作业采用构造表达式树的方式。
-
在Bracketmatch中用堆栈的方式匹配表达式括号,将其转为一个字符A.
-
在Paring和Term中对表达式进行解析,与第一次作业一样,用split分离,再对Term中得到的因子进行分析。
-
Sin、Cos、Pow、Const类中将diff()和toString()进行重写,Mul作为乘法节点,Add作为加法节点,这些类都继承与BasePoint类。
代码复杂度分析
类复杂度
| class | OCavg | OCmax | WMC |
|---|---|---|---|
| Add | 1.00 | 1 | 3 |
| BasePoint | 0 | ||
| Bracketmatch | 5.00 | 5 | 5 |
| Const | 1.00 | 1 | 3 |
| Cos | 1.67 | 3 | 5 |
| Main | 2.00 | 2 | 2 |
| Mul | 1.00 | 1 | 3 |
| Parsing | 2.00 | 4 | 10 |
| Pow | 1.67 | 3 | 5 |
| Sin | 1.67 | 3 | 5 |
| Term | 5.00 | 9 | 10 |
| Total | 51 | ||
| Average | 1.89 | 3.20 | 4.64 |
方法复杂度
| method | CogC | ev(G) | iv(G) | v(G) |
|---|---|---|---|---|
| Add.Add(BasePoint,BasePoint) | 0 | 1 | 1 | 1 |
| Add.diff() | 0 | 1 | 1 | 1 |
| Add.toString() | 0 | 1 | 1 | 1 |
| Const.Const(BigInteger) | 0 | 1 | 1 | 1 |
| Const.diff() | 0 | 1 | 1 | 1 |
| Const.toString() | 0 | 1 | 1 | 1 |
| Cos.Cos(BigInteger) | 0 | 1 | 1 | 1 |
| Cos.diff() | 0 | 1 | 1 | 1 |
| Main.main(String[]) | 2 | 1 | 3 | 4 |
| Mul.Mul(BasePoint,BasePoint) | 0 | 1 | 1 | 1 |
| Mul.diff() | 0 | 1 | 1 | 1 |
| Mul.toString() | 0 | 1 | 1 | 1 |
| Parsing.Bracketfactor(String) | 8 | 1 | 4 | 4 |
| Parsing.Parsing() | 0 | 1 | 1 | 1 |
| Parsing.Parsing(String) | 1 | 1 | 2 | 2 |
| Parsing.getBrast(String) | 1 | 1 | 2 | 2 |
| Parsing.getFactor() | 0 | 1 | 1 | 1 |
| Pow.Pow(BigInteger) | 0 | 1 | 1 | 1 |
| Pow.diff() | 0 | 1 | 1 | 1 |
| Sin.Sin(BigInteger) | 0 | 1 | 1 | 1 |
| Sin.diff() | 0 | 1 | 1 | 1 |
| Term.Term(String,ArrayList) | 16 | 1 | 8 | 9 |
| Term.getRe() | 0 | 1 | 1 | 1 |
| Cos.toString() | 3 | 3 | 2 | 3 |
| Pow.toString() | 3 | 3 | 2 | 3 |
| Sin.toString() | 3 | 3 | 2 | 3 |
| Bracketmatch.getFactor(String) | 7 | 5 | 5 | 5 |
| Total | 44 | 37 | 48 | 53 |
| Average | 1.63 | 1.37 | 1.78 | 1.96 |
从表格中可以看到Term类中的构造函数Term(String,ArrayList<String>)复杂度较高,原因是在这里进行了因子的判断,而没有通过Factory来进行。
Bug分析
这次作业并没有上交(900秒一次的冷却CD真长),但在课下自我测试的时候也发现了一些bug,最开始的时候是括号的处理,如果三角函数嵌套三角函数的时候容易出现错误,其次就是toString中的一些小错误,导致输出与理想不符。
小结
第二次作业没有过中测,刚开始的时候想着对第一次作业进行修改,看看能不能完成,但最后才发现,第一次作业的构架无法适应第二次的要求,无奈重构,最后在ddl前十几分钟写完,提交后才发现一堆bug,失败。
第三次作业
类图

构架设计
-
这一次的构架与第二次作业基本相同,只不过将Add放在了Poly中,将Mul放在了Term中。仍然是Poly对表达式分析,Term对项分析。
-
还是没有建立Factory类,但事后发现,建立Factory类可以减少很多代码量,节省很多时间。
-
新建了CheckExp类用于对表达式合法性的初步判断
代码复杂度分析
类复杂度
| class | OCavg | OCmax | WMC |
|---|---|---|---|
| CheckExp | 3.00 | 7 | 9 |
| Cons | 1.33 | 2 | 4 |
| Cos | 5.33 | 9 | 16 |
| Main | 2.00 | 2 | 2 |
| Poly | 5.33 | 10 | 16 |
| Power | 3.67 | 4 | 11 |
| Sin | 5.33 | 9 | 16 |
| Term | 6.67 | 10 | 20 |
| Total | 94 | ||
| Average | 4.27 | 6.62 | 11.75 |
方法复杂度
| method | CogC | ev(G) | iv(G) | v(G) |
|---|---|---|---|---|
| CheckExp.CheckExp() | 0 | 1 | 1 | 1 |
| CheckExp.getSt() | 0 | 1 | 1 | 1 |
| Cons.Cons(String) | 2 | 1 | 2 | 2 |
| Cons.diff() | 0 | 1 | 1 | 1 |
| Cons.toString() | 0 | 1 | 1 | 1 |
| Cos.Cos(String) | 9 | 1 | 4 | 8 |
| Main.main(String[]) | 3 | 1 | 3 | 3 |
| Poly.diff() | 3 | 1 | 3 | 3 |
| Poly.toString() | 3 | 1 | 3 | 3 |
| Power.Power(String) | 7 | 1 | 4 | 4 |
| Sin.Sin(String) | 9 | 1 | 4 | 8 |
| Term.Term(String) | 10 | 1 | 6 | 11 |
| Term.toString() | 3 | 1 | 3 | 3 |
| Cos.diff() | 5 | 2 | 3 | 4 |
| Sin.diff() | 5 | 2 | 3 | 4 |
| Cos.toString() | 3 | 3 | 3 | 3 |
| Power.diff() | 3 | 3 | 3 | 4 |
| Power.toString() | 3 | 3 | 2 | 3 |
| Sin.toString() | 3 | 3 | 3 | 3 |
| Term.diff() | 17 | 5 | 7 | 9 |
| CheckExp.isLeagal(String) | 6 | 7 | 1 | 7 |
| Poly.Poly(String) | 28 | 9 | 13 | 20 |
| Total | 122 | 50 | 74 | 106 |
| Average | 5.55 | 2.27 | 3.36 | 4.82 |
可以看到,Term类中的Term(String)和Poly类的Poly(String)都较为复杂,主要是因为在对表达式进行解析式,运用了较多的if-else判断和for,while循环。同时,Term类中的diff()在将因子进行合并时较为复杂,用了for和if的嵌套结构。
Bug分析
作业三的bug主要在于对表达式合法性的判断,在强测时没有注意到括号后的因子只有一个符号,中间不能有空格,但我使用的正则表达式中没有处理这个问题,导致错误,其次是对括号中没有因子的格式判断,这个问题是我在解析项的时候没有注意到。
小结
第三次作业是在第二次作业基础上完成的,虽然又一次重构,但很明显比第一次重构熟练很多,主要是对表达式树和面向对象的逐渐熟悉,以及继承的应用,但是还是没有运用工厂模式,导致代码相对复杂。
总结
-
寒假偷懒,pre一点没写,来到学校之后也没有重视pre,对Java很不熟悉,吃了很大的亏。
-
每次作业都进行了重构,逐渐对Java熟悉,但过程很痛苦。
-
在完成作业的过程中开始从面向过程转变为面向对象。
-
很遗憾第二次作业没完成,还是要更加重视OO的作业。

浙公网安备 33010602011771号