第一单元总结博客 19373048 徐柯轩
第一单元总结博客
19373048 徐柯轩
一、基于度量来分析自己的程序结构
(一)第一次作业
1. 设计思路 (1)字符串分解 根据题意可知,项和表达式均采用“递归定义”的方式给出规范格式。自然得出分别匹配初始条件(第一项或第一个表达式)和归纳条件(第一个以外的项或表达式)的字符串分解思路。将字符串进行正确分解后,自然就可以得到对应的项和表达式。(2)求导 只是修改所得到的项的系数。(3)化简 只是将相同指数的系数进行合并。
2. 度量分析
Expression.checkDevelopStringP(String) |
7.0 |
3.0 |
5.0 |
5.0 |
Expression.checkOriginStringP(String,String) |
6.0 |
1.0 |
5.0 |
5.0 |
Expression.differential() |
1.0 |
1.0 |
2.0 |
2.0 |
Expression.Expression(String) |
0.0 |
1.0 |
1.0 |
1.0 |
Expression.getExpression() |
13.0 |
1.0 |
7.0 |
7.0 |
Expression.setTermArrayList() |
0.0 |
1.0 |
1.0 |
1.0 |
Expression.simplify() |
6.0 |
1.0 |
5.0 |
5.0 |
ExpressionDifferential.main(String[]) |
0.0 |
1.0 |
1.0 |
1.0 |
ExpressionDifferential.readExpression() |
0.0 |
1.0 |
1.0 |
1.0 |
ExpressionDifferential.writeDifferentialExpression() |
0.0 |
1.0 |
1.0 |
1.0 |
null.compare(Term,Term) |
0.0 |
|||
Term.differential() |
1.0 |
1.0 |
2.0 |
2.0 |
Term.getAttribute() |
0.0 |
1.0 |
1.0 |
1.0 |
Term.getIndex() |
0.0 |
1.0 |
1.0 |
1.0 |
Term.readAttribute() |
11.0 |
4.0 |
6.0 |
7.0 |
Term.readIndex() |
5.0 |
3.0 |
4.0 |
4.0 |
Term.setAttribute(BigDecimal) |
0.0 |
1.0 |
1.0 |
1.0 |
Term.setIndex(BigDecimal) |
0.0 |
1.0 |
1.0 |
1.0 |
Term.Term(String,BigDecimal) |
0.0 |
1.0 |
1.0 |
1.0 |
Total |
50.0 |
25.0 |
46.0 |
47.0 |
Average |
2.6315789473684212 |
1.3888888888888888 |
2.5555555555555554 |
2.611111111111111 |
表1 第一次作业-方法复杂度
Expression |
3.0 |
6.0 |
24.0 |
ExpressionDifferential |
1.0 |
1.0 |
3.0 |
Term |
2.125 |
6.0 |
17.0 |
Total |
44.0 |
||
Average |
2.3157894736842106 |
4.333333333333333 |
14.666666666666666 |
表2 第一次作业-类复杂度
(二)第二次作业
1. 设计思路 (1)字符串分解 因为第二次作业中添加了“表达式因子”的概念,导致第一次作业的字符串分解方法失效,进而无法得到正确的项和表达式。在与同学进行相关讨论后,我产生了一个全新的思路:与 C 语言按下标读取字符串的方法类似,我将一个简单因子(非表达式因子)作为一个独立的读取单位。从左向右扫描字符串并读取因子,如果遇到运算符,则根据运算符的内容进行相应的逻辑操作。如果遇到“*”则继续读取,如果遇到“+/-”则生成一个新项,如果遇到“(”则向下递归构造新表达式,直到“)”为止,并将读取后的字符串返回。(2)求导 因为加入了乘法运算,因此不能简单地修改各因子的系数。在这次作业中,我引入了“不可变类”的概念,将 Term 修改为“不可变类”,一个 Term 求导生成的是一个 ArrayList <Term> 的聚合。其中,线性表的每一项都是互相独立的“不可变类”。(3)化简 因为时间原因,并没有进行化简操作
2. 度量分析
DifferentiateExpression.input() |
0.0 |
1.0 |
1.0 |
1.0 |
DifferentiateExpression.main(String[]) |
0.0 |
1.0 |
1.0 |
1.0 |
DifferentiateExpression.output() |
0.0 |
1.0 |
1.0 |
1.0 |
Expression.differentiate() |
5.0 |
1.0 |
5.0 |
5.0 |
Expression.Expression(ArrayList) |
0.0 |
1.0 |
1.0 |
1.0 |
Expression.Expression(String) |
10.0 |
3.0 |
6.0 |
7.0 |
Expression.getArrayListTerm() |
0.0 |
1.0 |
1.0 |
1.0 |
Expression.getStringReturn() |
0.0 |
1.0 |
1.0 |
1.0 |
Expression.merge(Expression) |
3.0 |
1.0 |
3.0 |
3.0 |
Expression.merge(Term) |
1.0 |
1.0 |
2.0 |
2.0 |
Expression.setTerm(String) |
34.0 |
3.0 |
14.0 |
15.0 |
Expression.simplify() |
4.0 |
1.0 |
4.0 |
4.0 |
Expression.sort() |
7.0 |
3.0 |
5.0 |
5.0 |
Expression.toString() |
4.0 |
1.0 |
3.0 |
4.0 |
null.compare(Term,Term) |
3.0 |
|||
Term.addIndexCos(BigDecimal) |
0.0 |
1.0 |
1.0 |
1.0 |
Term.addIndexSin(BigDecimal) |
0.0 |
1.0 |
1.0 |
1.0 |
Term.addIndexX(BigDecimal) |
0.0 |
1.0 |
1.0 |
1.0 |
Term.addMemberArrayListExpression(Expression) |
0.0 |
1.0 |
1.0 |
1.0 |
Term.differentiate() |
4.0 |
1.0 |
5.0 |
5.0 |
Term.differentiateCos() |
0.0 |
1.0 |
1.0 |
1.0 |
Term.differentiateExpression() |
1.0 |
1.0 |
2.0 |
2.0 |
Term.differentiateSin() |
0.0 |
1.0 |
1.0 |
1.0 |
Term.differentiateX() |
0.0 |
1.0 |
1.0 |
1.0 |
Term.equals(Term) |
1.0 |
1.0 |
3.0 |
3.0 |
Term.getIndexCos() |
0.0 |
1.0 |
1.0 |
1.0 |
Term.getIndexSin() |
0.0 |
1.0 |
1.0 |
1.0 |
Term.getIndexX() |
0.0 |
1.0 |
1.0 |
1.0 |
Term.getValueCons() |
0.0 |
1.0 |
1.0 |
1.0 |
Term.isZero() |
0.0 |
1.0 |
1.0 |
1.0 |
Term.merge(Term) |
0.0 |
1.0 |
1.0 |
1.0 |
Term.multiplyValueCons(BigDecimal) |
0.0 |
1.0 |
1.0 |
1.0 |
Term.setValueCons(BigDecimal) |
0.0 |
1.0 |
1.0 |
1.0 |
Term.simplify() |
6.0 |
1.0 |
4.0 |
4.0 |
Term.Term() |
0.0 |
1.0 |
1.0 |
1.0 |
Term.Term(BigDecimal) |
0.0 |
1.0 |
1.0 |
1.0 |
Term.Term(BigDecimal,BigDecimal,BigDecimal,BigDecimal,BigDecimal,ArrayList) |
0.0 |
1.0 |
1.0 |
1.0 |
Term.toString() |
19.0 |
1.0 |
12.0 |
16.0 |
Term.unsign() |
0.0 |
1.0 |
1.0 |
1.0 |
Total |
102.0 |
44.0 |
93.0 |
100.0 |
Average |
2.6153846153846154 |
1.1578947368421053 |
2.4473684210526314 |
2.6315789473684212 |
表3 第二次作业-方法复杂度
DifferentiateExpression |
1.0 |
1.0 |
3.0 |
Expression |
4.0 |
15.0 |
48.0 |
Term |
1.7916666666666667 |
12.0 |
43.0 |
Total |
94.0 |
||
Average |
2.41025641025641 |
9.333333333333334 |
31.333333333333332 |
表4 第二次作业-类复杂度
(三)第三次作业
1. 设计思路 (1)字符串分解 与第二次作业类似,只是将原来过大的单一方法进行了拆解。(2)求导 与第二次不同,在保留“不可变类”的基础上,这次作业引入了 Expression、Term、Factor、Function 四个层次,Factor(包括Function)求导生成 Term,Term 求导生成 Expression,Expression 求导生成 Expression,不同类之间的接口更加合理。同时在 Factor 中引入 FactorExpression 专门管理表达式因子,使 Term 和 Expression 解耦。(3)化简 并没有进行深入的研究,只是将 FactorCons (常数项)和 FunctionX(幂函数)进行了合并。
2. 度量分析
DifferentiateExpression.creatExpression() |
1.0 |
1.0 |
1.0 |
2.0 |
DifferentiateExpression.differentiateExpression() |
0.0 |
1.0 |
1.0 |
1.0 |
DifferentiateExpression.inputExpression() |
1.0 |
2.0 |
1.0 |
2.0 |
DifferentiateExpression.isBraceChecked() |
9.0 |
6.0 |
5.0 |
7.0 |
DifferentiateExpression.main(String[]) |
1.0 |
1.0 |
2.0 |
2.0 |
DifferentiateExpression.outputExpression() |
0.0 |
1.0 |
1.0 |
1.0 |
Expression.differentiate() |
1.0 |
1.0 |
2.0 |
2.0 |
Expression.Expression() |
0.0 |
1.0 |
1.0 |
1.0 |
Expression.Expression(ArrayList) |
0.0 |
1.0 |
1.0 |
1.0 |
Expression.Expression(String) |
22.0 |
11.0 |
10.0 |
14.0 |
Expression.getStringExpressionRest() |
0.0 |
1.0 |
1.0 |
1.0 |
Expression.nextFactor(BigDecimal) |
6.0 |
6.0 |
1.0 |
7.0 |
Expression.nextFactorCons(BigDecimal) |
1.0 |
2.0 |
2.0 |
2.0 |
Expression.nextFactorExpression(BigDecimal) |
4.0 |
3.0 |
3.0 |
4.0 |
Expression.nextFunctionCos(BigDecimal) |
14.0 |
5.0 |
5.0 |
7.0 |
Expression.nextFunctionSin(BigDecimal) |
14.0 |
5.0 |
5.0 |
7.0 |
Expression.nextFunctionX(BigDecimal) |
8.0 |
4.0 |
4.0 |
5.0 |
Expression.nextSign() |
2.0 |
3.0 |
3.0 |
3.0 |
Expression.remoteSpace() |
2.0 |
1.0 |
3.0 |
3.0 |
Expression.simplify() |
4.0 |
1.0 |
4.0 |
4.0 |
Expression.toString() |
3.0 |
1.0 |
2.0 |
3.0 |
FactorCons.differentiate() |
0.0 |
1.0 |
1.0 |
1.0 |
FactorCons.FactorCons(BigDecimal,BigDecimal) |
0.0 |
1.0 |
1.0 |
1.0 |
FactorCons.getSign() |
0.0 |
1.0 |
1.0 |
1.0 |
FactorCons.getStringPattern() |
0.0 |
1.0 |
1.0 |
1.0 |
FactorCons.getValue() |
0.0 |
1.0 |
1.0 |
1.0 |
FactorCons.toString() |
0.0 |
1.0 |
1.0 |
1.0 |
FactorExpression.differentiate() |
0.0 |
1.0 |
1.0 |
1.0 |
FactorExpression.FactorExpression(Expression,BigDecimal) |
0.0 |
1.0 |
1.0 |
1.0 |
FactorExpression.getExpression() |
0.0 |
1.0 |
1.0 |
1.0 |
FactorExpression.toString() |
2.0 |
2.0 |
2.0 |
2.0 |
FunctionCos.differentiate() |
2.0 |
1.0 |
2.0 |
2.0 |
FunctionCos.FunctionCos(BigDecimal,Factor,BigDecimal) |
0.0 |
1.0 |
1.0 |
1.0 |
FunctionCos.getFactor() |
0.0 |
1.0 |
1.0 |
1.0 |
FunctionCos.getStringPatternFunction() |
0.0 |
1.0 |
1.0 |
1.0 |
FunctionCos.getStringPatternIndex() |
0.0 |
1.0 |
1.0 |
1.0 |
FunctionCos.toString() |
4.0 |
1.0 |
3.0 |
4.0 |
FunctionSin.differentiate() |
2.0 |
1.0 |
2.0 |
2.0 |
FunctionSin.FunctionSin(BigDecimal,Factor,BigDecimal) |
0.0 |
1.0 |
1.0 |
1.0 |
FunctionSin.getFactor() |
0.0 |
1.0 |
1.0 |
1.0 |
FunctionSin.getStringPatternFunction() |
0.0 |
1.0 |
1.0 |
1.0 |
FunctionSin.getStringPatternIndex() |
0.0 |
1.0 |
1.0 |
1.0 |
FunctionSin.toString() |
4.0 |
1.0 |
3.0 |
4.0 |
FunctionX.differentiate() |
2.0 |
1.0 |
2.0 |
2.0 |
FunctionX.FunctionX(BigDecimal,BigDecimal) |
0.0 |
1.0 |
1.0 |
1.0 |
FunctionX.getIndex() |
0.0 |
1.0 |
1.0 |
1.0 |
FunctionX.getSign() |
0.0 |
1.0 |
1.0 |
1.0 |
FunctionX.getStringPattern() |
0.0 |
1.0 |
1.0 |
1.0 |
FunctionX.toString() |
5.0 |
1.0 |
3.0 |
5.0 |
Term.differentiate() |
1.0 |
1.0 |
2.0 |
2.0 |
Term.getArrayListFactor() |
0.0 |
1.0 |
1.0 |
1.0 |
Term.isZero() |
1.0 |
1.0 |
3.0 |
3.0 |
Term.merge(Term,int) |
4.0 |
3.0 |
3.0 |
3.0 |
Term.simplify() |
23.0 |
1.0 |
16.0 |
16.0 |
Term.Term(ArrayList,BigDecimal) |
0.0 |
1.0 |
1.0 |
1.0 |
Term.Term(Factor,BigDecimal) |
0.0 |
1.0 |
1.0 |
1.0 |
Term.toString() |
4.0 |
1.0 |
2.0 |
4.0 |
WrongFormatException.WrongFormatException() |
0.0 |
1.0 |
1.0 |
1.0 |
Total |
147.0 |
98.0 |
126.0 |
153.0 |
Average |
2.5344827586206895 |
1.6896551724137931 |
2.1724137931034484 |
2.6379310344827585 |
表5 第三次作业-方法复杂度
DifferentiateExpression |
2.0 |
6.0 |
12.0 |
Expression |
3.533333333333333 |
11.0 |
53.0 |
FactorCons |
1.0 |
1.0 |
6.0 |
FactorExpression |
1.25 |
2.0 |
5.0 |
FunctionCos |
1.6666666666666667 |
4.0 |
10.0 |
FunctionSin |
1.6666666666666667 |
4.0 |
10.0 |
FunctionX |
1.8333333333333333 |
5.0 |
11.0 |
Term |
3.25 |
13.0 |
26.0 |
WrongFormatException |
1.0 |
1.0 |
1.0 |
Total |
134.0 |
||
Average |
2.310344827586207 |
5.222222222222222 |
14.88888888888889 |
表6 第三次作业-类复杂度
3. 类图绘制
图1 第三次作业-类图绘制
二、分析自己的 BUG
(一)第一次作业
虽然在识别表达式的过程中,采用了“递归定义”的分析的方法;但在识别项的过程中,依然采用了“大正则表达式”的传统方法。这导致了在互测过程中,因为输入的项过长而爆栈。
(二)第二次作业
此次作业尚未被 hack。
(三)第三次作业
虽然采用了比较“面向对象”的设计思路,也顺利地通过了中测。然而,在实现过程中,由于未能进行有效的 debug,导致出现两个非常严重的失误:a. 忘记为 FactorExpression 项添加符号,导致在求导过程中出现符号错误;b. 强制将 x**2 输出为 x*x,导致出现 sin(x*x) 的错误输出结果。
三、分析自己发现别人程序 BUG 所采用的策略
只是将自己在提交前出现的可能错误进行提交。
四、重构经历总结
(一)第二次作业
第二次作业是一次彻底的重写,除了“DifferentiateExpression-Expression-Term”的整体结构相同外,每个类的细节均进行了重写。
(二)第三次作业
第三次作业虽然和第二次作业整体结构有一些区别,但并没有进行大规模的重写:将一些 Expression 和 Term 中的过长方法进行拆分,封装到具体的类中;并添加 FactorExpression 实现表达式因子的功能。
五、心得体会
通过三周的学习,我逐渐掌握了“面向对象”的含义,学会了一些常用的设计模式。在解决问题的实践中,我明白了一些建立抽象的实现手段。但同时,三周作业也暴露出我在“测试”方面的知识漏洞。这直接导致了我第三次上机作业的严重失误。希望在今后的作业中,我能在巩固“面向对象”思想的同时,加强自身对“测试”的研究和实践。