BUAA-OO-2021 第一单元作业

BUAA OO 第一单元总结

第一次作业

设计思路

总体思路

第一次作业还比较面向过程,本人采用PolyFactory 类用来处理输入同时生成Polynomial类和Term类。

Polynomial 类用来维护整个表达式,Term 类用了维护每个项的系数和幂次。

输入处理

PolyFactory 类中采用不断replace和split的方式分割了每个项,再对项分割因子。

求导思路

新建一个空的新Polynomial,对旧Polynomial的每个Term求导,再依次加入新Polynomial。

化简思路

  • 合并同类项,这个用hashmap维护即可。
  • 优先输出系数为正的项,这样可以省一个负号,toString的时候排个序就行了。
  • \(x**1\to x\),toString的时候特判即可。
  • \(1*x**k\to x**k,-1*x**k\to -x**k\),toString的时候特判即可。
  • \(x**2\to x*x\),toString的时候特判即可。

类关系图

diagram1

复杂度分析

方法复杂度

Method CogC ev(G) iv(G) v(G)
MainClass.main(String[]) 0 1 1 1
PolyFactory.producePoly(String) 3 1 3 4
PolyFactory.produceTerm(String) 14 1 6 6
Polynomial.Polynomial() 0 1 1 1
Polynomial.add(Term) 4 1 3 3
Polynomial.derivation() 1 1 2 2
Polynomial.toString() 2 2 2 3
Term.Term(BigInteger,BigInteger) 0 1 1 1
Term.add(Term) 0 1 1 1
Term.compareByCoefficient(Term) 0 1 1 1
Term.derivation() 0 1 1 1
Term.getCoefficient() 0 1 1 1
Term.getDegree() 0 1 1 1
Term.toString() 9 2 5 6

类复杂度

Class OCavg OCmax WMC
MainClass 1 1 1
PolyFactory 4.5 6 9
Polynomial 2.25 3 9
Term 1.71 6 12

代码行数

statistic1

复杂度评价

整体来说这次作业难度较低,因此代码也比较简单,基本符合高内聚低耦合的设计准则。

其中PolyFactory的OCavg偏高,原因是PolyFactory的produceTerm函数写的比较复杂,用了很多特判,比较面向过程。

测试相关

本人强测与互测均未被发现BUG,并成功hack别人两次,hack时没有看别人代码而是进行黑盒测试。

hack数据为手动构造,主要利用爆栈hack了用了正则的代码。

自己写了自动测评机来找自己的BUG和hack别人的代码,但测评机没有成功hack到别人的代码。

第二次作业

设计思路

总体思路

第二次作业开始面向对象了,其中ExpressionGenerator用于处理输入同时生成Expression类。

Expression类用于求导,Poly类用于化简。

输入处理

自学并实现了递归下降,处理式子前直接replace了空白字符和多重正负号,因此实现过程中暂时没有实现 Wrong Format的判定和处理。

求导思路

首先分析式子,发现式子仅包含常数,变量,\(\sin\) 函数,cos函数,幂函数,加法,减法,乘法。

归根到底,常量、变量、单/二元操作符。

而对于求导,不难发现,求导最底层一定是 \(常数'=0,x'=1\),然后通过各种单/二元操作符连接结果。

通过上述分析,很自然得到了对象的设计思路,对象即 \(x\) 和常数和所有单/二元操作符。

写一个抽象类 Expression,然后只需要 Expression 的所有子类支持求导即可,求导即按上述求导方法递归求解。

化简思路

  • \(1*f(x)=f(x)\)
  • \(0*f(x)=0\)
  • \(f(x)^0=1\)
  • \(f(x)^1=f(x)\)
  • \(f(x)^a*f(x)^b=f(x)^{a+b}\)
  • \(af(x)+bf(x)=(a+b)f(x)\)
  • \((f(x))=f(x)\)
  • \(x**2=x*x\)
  • 正系数前移,例如 \(-x+x^2=x^2-x\)

专门为化简写了一个Poly类,Poly的每个子类支持化简simply,然后为每个类写一个加法合并函数addMerge和乘法合并函数mulMerge用于合并同类项。

类关系图

diagram2

复杂度分析

方法复杂度

Method CogC ev(G) iv(G) v(G)
AddExpression.AddExpression(Expression,Expression) 0 1 1 1
AddExpression.derivation() 0 1 1 1
AddExpression.rebuild() 0 1 1 1
AddExpression.simplify() 5 4 4 5
AddExpression.toString() 0 1 1 1
ConstPoly.ConstPoly(BigInteger) 0 1 1 1
ConstPoly.addMerge(Poly) 2 2 2 2
ConstPoly.canAddMerge(Poly) 0 1 1 1
ConstPoly.canMulMerge(Poly) 0 1 1 1
ConstPoly.mulMerge(Poly) 2 2 2 2
ConstPoly.toString() 0 1 1 1
ConstPoly.toStringAsFactor() 0 1 1 1
Constant.Constant(BigInteger) 0 1 1 1
Constant.add(Constant) 0 1 1 1
Constant.derivation() 0 1 1 1
Constant.mul(Constant) 0 1 1 1
Constant.rebuild() 0 1 1 1
Constant.toString() 0 1 1 1
CosExpression.CosExpression(Expression) 0 1 1 1
CosExpression.derivation() 0 1 1 1
CosExpression.rebuild() 0 1 1 1
CosExpression.toString() 0 1 1 1
CosPoly.CosPoly(BigInteger) 0 1 1 1
CosPoly.CosPoly(BigInteger,BigInteger) 0 1 1 1
CosPoly.addMerge(Poly) 6 4 4 4
CosPoly.canAddMerge(Poly) 2 2 2 2
CosPoly.canMulMerge(Poly) 0 1 1 1
CosPoly.mulMerge(Poly) 8 6 6 6
CosPoly.toString() 2 1 3 3
CosPoly.toStringAsFactor() 1 1 2 2
Expression.Expression() 0 1 1 1
Expression.simplify() 0 1 1 1
ExpressionGenerator.ExpressionGenerator(String) 0 1 1 1
ExpressionGenerator.expression() 3 1 3 3
ExpressionGenerator.factor() 19 6 11 13
ExpressionGenerator.generateExpression() 0 1 1 1
ExpressionGenerator.readInt() 1 1 2 2
ExpressionGenerator.term() 2 1 2 2
MainClass.main(String[]) 3 3 2 3
MulExpression.MulExpression(Expression,Expression) 0 1 1 1
MulExpression.derivation() 0 1 1 1
MulExpression.rebuild() 0 1 1 1
MulExpression.simplify() 7 5 6 7
MulExpression.toString() 2 1 1 3
Poly.Poly(BigInteger) 0 1 1 1
Poly.addMerge(Poly) 0 1 1 1
Poly.canAddMerge(Poly) 0 1 1 1
Poly.canMulMerge(Poly) 0 1 1 1
Poly.compareCoefficient(Poly) 0 1 1 1
Poly.getCoefficient() 0 1 1 1
Poly.mulMerge(Poly) 0 1 1 1
Poly.setCoefficient(BigInteger) 0 1 1 1
Poly.simply() 0 1 1 1
PowExpression.PowExpression(Expression,BigInteger) 0 1 1 1
PowExpression.derivation() 3 3 3 3
PowExpression.rebuild() 4 4 1 4
PowExpression.toString() 3 3 3 3
ProdPoly.ProdPoly() 0 1 1 1
ProdPoly.addMerge(Poly) 2 2 2 2
ProdPoly.insertPloy(Poly) 7 4 4 4
ProdPoly.mulMerge(Poly) 4 1 3 3
ProdPoly.simply() 6 3 5 5
ProdPoly.toString() 4 2 5 5
ProdPoly.toStringAsFactor() 0 1 1 1
SinExpression.SinExpression(Expression) 0 1 1 1
SinExpression.derivation() 0 1 1 1
SinExpression.rebuild() 0 1 1 1
SinExpression.toString() 0 1 1 1
SinPoly.SinPoly(BigInteger) 0 1 1 1
SinPoly.SinPoly(BigInteger,BigInteger) 0 1 1 1
SinPoly.addMerge(Poly) 6 4 4 4
SinPoly.canAddMerge(Poly) 2 2 2 2
SinPoly.canMulMerge(Poly) 0 1 1 1
SinPoly.mulMerge(Poly) 8 6 6 6
SinPoly.toString() 2 1 3 3
SinPoly.toStringAsFactor() 1 1 2 2
SumPoly.SumPoly() 0 1 1 1
SumPoly.SumPoly(BigInteger,ArrayList) 0 1 1 1
SumPoly.addMerge(Poly) 0 1 1 1
SumPoly.addPoly(Poly) 4 1 3 3
SumPoly.insertPloy(Poly) 6 4 4 4
SumPoly.mulMerge(Poly) 4 4 4 4
SumPoly.setCoefficient(BigInteger) 1 1 2 2
SumPoly.simply() 5 3 4 4
SumPoly.toString() 2 2 2 3
SumPoly.toStringAsFactor() 2 2 2 3
VarPoly.VarPoly(BigInteger) 0 1 1 1
VarPoly.VarPoly(BigInteger,BigInteger) 0 1 1 1
VarPoly.addMerge(Poly) 6 4 4 4
VarPoly.canAddMerge(Poly) 2 2 2 2
VarPoly.canMulMerge(Poly) 0 1 1 1
VarPoly.mulMerge(Poly) 8 6 6 6
VarPoly.toString() 2 1 3 3
VarPoly.toStringAsFactor() 4 1 3 3
Variable.Variable() 0 1 1 1
Variable.derivation() 0 1 1 1
Variable.rebuild() 0 1 1 1
Variable.toString() 0 1 1 1

类复杂度

Class OCavg OCmax WMC
AddExpression 1.6 4 8
ConstPoly 1.29 2 9
Constant 1 1 6
CosExpression 1 1 4
CosPoly 2.5 6 20
Expression 1 1 2
ExpressionGenerator 3.33 12 20
MainClass 3 3 3
MulExpression 2.2 5 11
Poly 1 1 9
PowExpression 2.75 4 11
ProdPoly 2.86 5 20
SinExpression 1 1 4
SinPoly 2.5 6 20
SumPoly 2.6 4 26
VarPoly 2.62 6 21
Variable 1 1 4

代码行数

statistic2

复杂度评价

用于Poly类的设计不佳,导致合并同类项的过程异常繁琐,需要各种判定,导致Poly类中各个子类的addMerge和mulMerge函数的圈复杂度普遍偏高,同时代码量也直线上升。

同时本次作业采用二叉树求导和多叉树化简,同时需要实现二者之间的相互转换,这也导致了代码量的上升。

另外ExpressionGenerator类的复杂度也较大,主要原因是在递归下降中用了过多的条件判断语句。

测试相关

本人强测与互测均未被发现BUG,并成功hack别人三次,hack时没有看别人代码而是进行黑盒测试。

hack数据为手动构造,主要利用表达式套娃hack成功两次,另外通过 \(\sin^2(x)+\cos^2(x)\) hack到别人一次,估计是别人忘了判定表达式求导并化简后为空的情况。

自己写了自动测评机来找自己的BUG和hack别人的代码,但测评机没有成功hack到别人的代码。

第三次作业

设计思路

总体思路

第三次作业主要在第二次作业上重构了化简类,第二次作业的求导类已经满足第三次作业的需求了。

输入处理

对递归下降进行了调整,感觉算法更接近自动机了,完全依照指导书的形式化表达来构建代码,实现了 Wrong Format的判定和处理,自动机流程如下图。

\[E\to [+-]T|[+-]TE'\\ E'\to +T|-T|+TE'|-TE'\\ T\to [+|-]F|[+|-]FT'\\ T'\to *F|*FT' \\ F\to \text{变量因子|常数因子|(E)} \]

求导思路

由于第二次作业已经满足第三次作业的求导需求,因此没有修改。

化简思路

  • \(1*f(x)=f(x)\)

  • \(0*f(x)=0\)

  • \(f(x)^0=1\)

  • \(f(x)^1=f(x)\)

  • \(f(x)^a*f(x)^b=f(x)^{a+b}\)

  • \(af(x)+bf(x)=(a+b)f(x)\)

  • \((f(x))=f(x)\)

  • \(\sin(0)=0\)

  • \(\cos(0)=1\)

  • \(\cos(-a)=\cos(a)(a\gt 0)\)

  • \(x**2=x*x\)

  • 正系数前移,例如 \(-x+x^2=x^2-x\)

  • \(a\sin^2(f(x))g(x)+b\cos^2(f(x))g(x)=ag(x)+(b-a)\cos^2(f(x))g(x)(a\le b)\)

  • \(f(x)h(x)+g(x)h(x)=(f(x)+g(x))h(x)\)

  • \(\cos((-1*\text{变量因子}^k))=\cos(\text{变量因子}^k)\)

  • 乘法展开

同类项合并优化

利用多叉树和hashMap实现项的合并,于是首先需要实现同类项判定。

完全正确的同类项判定是非常困难的,这里只考虑同类项判定的充分不必要条件。

对于三角函数直接判定三角函数类型以及内部是否相同即可,对幂函数判定幂函数底数和指数即可。

对连加类和连乘类用hashset 维护内容,然后直接调用 hashsetequal 即可。

显然这样并不会将 \(\cos(2x)\)\(\cos^2(x)-\sin^2(x)\) 判定相等,但大部分相等的式子还是可以正确判定的。

而且误将相等的式子判定为不相等并不会影响程序正确性,最多影响一点性能。

另外根据第二次作业失败经验,本次连乘类和连加类对子项类型进行了统一化处理,这样可以避免大量分类讨论。

连乘类的每个项必须是幂函数形式,同时维护一个系数。对于连加类,强制每个项必须是连乘项。

对于连乘项,合并同类项时开一个hashmap 记录每个因子的幂次,最后删除幂次为0的因子再重新生成 hashset

对于连加项,合并同类项时开一个hashmap记录每个项的系数,最后删除系数为0的因子再重新生成 hashset

括号嵌套的优化

递归调用子项的化简函数,然后对与连加和连乘项,特判子项个数为 \(1\) 的情况然后把子项提出来。

cos偶函数优化

化简时特判即可。

x*x优化

toString时特判即可,注意 \(\sin(x*x)\)\(\cos(x*x)\) 非法。

正系数前移优化

toString时对连加项中的连乘项根据系数进行排序。

三角优化

简单来说,对连加式,暴力二重遍历它的连乘项,对两个连乘项,考虑用两个 hashmap 维护两个连乘项因子的幂次,然后再求 \(min\),最后如果两个 hashmap 除以公因项后的内容正好是 \(a\sin^2(f(x))+b\cos^2(f(x))\) 的形式,直接合并即可,一直操作直到不存在可以合并的项位置。

因式分解优化

类似三角优化,合并条件改为公因子非空时进行合并。

乘法展开优化

本人只处理了常数乘以连加式的展开,仅需要更新连乘类的系数即可。

不稳定优化处理方案

对因式分解优化和乘法展开优化,最后结果有可能边长也有可能变短,于是本人考虑都试一遍然后取最短结果。

类关系图

diagram3

复杂度分析

方法复杂度

Method CogC ev(G) iv(G) v(G)
ExpressionGenerator.ExpressionGenerator(String) 2 2 2 3
ExpressionGenerator.eatChar() 0 1 1 1
ExpressionGenerator.eatDeg() 2 2 2 3
ExpressionGenerator.eatInt() 5 3 5 7
ExpressionGenerator.expression() 7 4 4 5
ExpressionGenerator.factor() 7 6 8 8
ExpressionGenerator.firstExpression() 6 2 4 5
ExpressionGenerator.firstTerm() 6 2 5 6
ExpressionGenerator.generateExpression() 1 2 1 2
ExpressionGenerator.getChar() 0 1 1 1
ExpressionGenerator.isSign() 1 1 2 2
ExpressionGenerator.skipChar(char) 1 2 1 2
ExpressionGenerator.skipSpace() 2 1 2 3
ExpressionGenerator.skipString(String) 1 1 2 2
ExpressionGenerator.term() 4 2 4 4
ExpressionGenerator.trigonometricFactor(String) 2 2 2 2
FormatException.FormatException() 0 1 1 1
MainClass.getString(Poly) 1 1 2 2
MainClass.main(String[]) 4 1 2 5
expression.AddExpression.AddExpression(Expression,Expression) 0 1 1 1
expression.AddExpression.derivation() 0 1 1 1
expression.AddExpression.rebuild() 0 1 1 1
expression.AddExpression.toString() 0 1 1 1
expression.Constant.Constant(BigInteger) 0 1 1 1
expression.Constant.derivation() 0 1 1 1
expression.Constant.rebuild() 0 1 1 1
expression.Constant.toString() 0 1 1 1
expression.CosExpression.CosExpression(Expression) 0 1 1 1
expression.CosExpression.derivation() 0 1 1 1
expression.CosExpression.rebuild() 0 1 1 1
expression.CosExpression.toString() 0 1 1 1
expression.MulExpression.MulExpression(Expression,Expression) 0 1 1 1
expression.MulExpression.derivation() 0 1 1 1
expression.MulExpression.rebuild() 0 1 1 1
expression.MulExpression.toString() 2 1 1 3
expression.PowExpression.PowExpression(Expression,BigInteger) 0 1 1 1
expression.PowExpression.derivation() 3 3 3 3
expression.PowExpression.rebuild() 0 1 1 1
expression.PowExpression.toString() 3 3 3 3
expression.SinExpression.SinExpression(Expression) 0 1 1 1
expression.SinExpression.derivation() 0 1 1 1
expression.SinExpression.rebuild() 0 1 1 1
expression.SinExpression.toString() 0 1 1 1
expression.Variable.Variable() 0 1 1 1
expression.Variable.derivation() 0 1 1 1
expression.Variable.rebuild() 0 1 1 1
expression.Variable.toString() 0 1 1 1
poly.ConstPoly.ConstPoly(BigInteger) 0 1 1 1
poly.ConstPoly.deepSimply() 0 1 1 1
poly.ConstPoly.equals(Object) 3 3 2 4
poly.ConstPoly.getCoefficient() 0 1 1 1
poly.ConstPoly.hashCode() 0 1 1 1
poly.ConstPoly.isNegate() 0 1 1 1
poly.ConstPoly.negate() 0 1 1 1
poly.ConstPoly.rebuild() 0 1 1 1
poly.ConstPoly.simply() 0 1 1 1
poly.ConstPoly.toString() 0 1 1 1
poly.CosPoly.CosPoly(Poly) 0 1 1 1
poly.CosPoly.deepSimply() 4 4 4 4
poly.CosPoly.rebuild() 0 1 1 1
poly.CosPoly.simply() 4 4 4 4
poly.CosPoly.toString() 0 1 1 1
poly.Poly.polyDiv(HashMap<Poly, BigInteger>,HashMap<Poly, BigInteger>) 1 1 2 2
poly.Poly.polyGcd(HashMap<Poly, BigInteger>,HashMap<Poly, BigInteger>) 3 1 3 3
poly.Poly.toHashMap(HashSet) 1 1 2 2
poly.PowPoly.PowPoly(Poly) 2 1 2 2
poly.PowPoly.PowPoly(Poly,BigInteger) 0 1 1 1
poly.PowPoly.canTriangleSimply(PowPoly) 2 2 4 4
poly.PowPoly.deepSimply() 0 1 1 1
poly.PowPoly.equals(Object) 4 3 3 5
poly.PowPoly.getDeg() 0 1 1 1
poly.PowPoly.getPoly() 0 1 1 1
poly.PowPoly.hashCode() 0 1 1 1
poly.PowPoly.rebuild() 0 1 1 1
poly.PowPoly.simply() 0 1 1 1
poly.PowPoly.singleSimply() 5 4 4 5
poly.PowPoly.toString() 9 1 7 7
poly.ProdPoly.ProdPoly(HashMap<Poly, BigInteger>,BigInteger) 1 1 2 2
poly.ProdPoly.ProdPoly(HashSet,BigInteger) 0 1 1 1
poly.ProdPoly.ProdPoly(Poly) 3 1 3 3
poly.ProdPoly.build(ArrayList,BigInteger) 2 1 3 3
poly.ProdPoly.compareCoefficient(ProdPoly) 0 1 1 1
poly.ProdPoly.deepSimply() 5 1 4 4
poly.ProdPoly.equals(Object) 4 3 3 5
poly.ProdPoly.getCoefficient() 0 1 1 1
poly.ProdPoly.getHashSet() 0 1 1 1
poly.ProdPoly.hashCode() 0 1 1 1
poly.ProdPoly.merge(Poly,Poly) 0 1 1 1
poly.ProdPoly.multiply(BigInteger) 0 1 1 1
poly.ProdPoly.rebuild() 6 1 3 5
poly.ProdPoly.setSimplyType(boolean) 0 1 1 1
poly.ProdPoly.simply() 5 1 4 4
poly.ProdPoly.singleSimply() 21 9 11 12
poly.ProdPoly.toString() 10 2 5 5
poly.SinPoly.SinPoly(Poly) 0 1 1 1
poly.SinPoly.deepSimply() 1 2 1 2
poly.SinPoly.rebuild() 0 1 1 1
poly.SinPoly.simply() 1 2 1 2
poly.SinPoly.toString() 0 1 1 1
poly.SumPoly.SumPoly(HashSet) 0 1 1 1
poly.SumPoly.SumPoly(Poly) 2 1 2 2
poly.SumPoly.build(ArrayList) 2 1 3 3
poly.SumPoly.deepSimply() 6 1 5 5
poly.SumPoly.equals(Object) 3 3 2 4
poly.SumPoly.gcdSimply() 3 1 3 4
poly.SumPoly.hashCode() 0 1 1 1
poly.SumPoly.merge(Poly,Poly) 0 1 1 1
poly.SumPoly.multiply(BigInteger) 1 1 2 2
poly.SumPoly.rebuild() 5 1 3 4
poly.SumPoly.simply() 5 1 4 4
poly.SumPoly.singleSimply() 3 3 3 3
poly.SumPoly.toString() 1 1 2 2
poly.SumPoly.triangleSimply() 3 1 3 4
poly.SumPoly.tryGcdSimply(Entry<HashSet, BigInteger>,Entry<HashSet, BigInteger>) 4 3 3 4
poly.SumPoly.tryGcdSimply(HashMap<HashSet, BigInteger>) 12 6 5 7
poly.SumPoly.tryTriangleSimply(Entry<HashSet, BigInteger>,Entry<HashSet, BigInteger>) 7 3 5 5
poly.SumPoly.tryTriangleSimply(HashMap<HashSet, BigInteger>) 12 6 5 7
poly.TrianglePoly.TrianglePoly(Poly) 0 1 1 1
poly.TrianglePoly.canTriangleSimply(Poly) 3 3 3 3
poly.TrianglePoly.equals(Object) 3 3 2 4
poly.TrianglePoly.getPoly() 0 1 1 1
poly.TrianglePoly.hashCode() 0 1 1 1
poly.TrianglePoly.toString() 5 1 4 5
poly.VarPoly.VarPoly() 0 1 1 1
poly.VarPoly.deepSimply() 0 1 1 1
poly.VarPoly.equals(Object) 2 2 2 3
poly.VarPoly.hashCode() 0 1 1 1
poly.VarPoly.rebuild() 0 1 1 1
poly.VarPoly.simply() 0 1 1 1
poly.VarPoly.toString() 0 1 1 1

类复杂度

Class OCavg OCmax WMC
ExpressionGenerator 2.62 6 42
FormatException 1 1 1
MainClass 3 4 6
expression.AddExpression 1 1 4
expression.Constant 1 1 4
expression.CosExpression 1 1 4
expression.Expression n/a n/a 0
expression.MulExpression 1.5 3 6
expression.PowExpression 2 3 8
expression.SinExpression 1 1 4
expression.Variable 1 1 4
poly.ConstPoly 1.2 3 12
poly.CosPoly 2.2 4 11
poly.Poly 2.33 3 7
poly.PowPoly 1.92 5 23
poly.ProdPoly 2.71 9 46
poly.SinPoly 1.4 2 7
poly.SumPoly 3.22 6 58
poly.TrianglePoly 2 3 12
poly.VarPoly 1.14 2 8

代码行数

statistic3_1

statistic3_2

复杂度评价

为了追求更好的性能,导致部分Poly的化简函数复杂度较高,特别是SumPoly的三角函数合并与因式分解合并显得异常复杂,代码行数也直线上升。

另外由于增加了Wrong Format的判定和处理,导致递归下降复杂度再次上升。

测试相关

本人强测未被发现BUG,互测被hack一次同时成功hack别人两次,hack时没有看别人代码而是进行黑盒测试。

hack数据为自动测评机构造,我本人也不清楚为什么别人会有这个BUG,只能说题目一旦复杂就什么BUG都有。

本人BUG为因式分解导致的BUG,触发原因为因式分解导致PowPoly的底数性质发生变化然而自己却忘记考虑了这种情况。

本质原因为为追求更好的性能导致代码过与复杂导致的BUG,这教会我以后要在性能分和正确性中做到更好的平衡。

重构经历总结

第一次作业的框架完全不能应用于第二次作业,于是第二次作业时对整个代码进行了重构。

第二次作业的求导框架已经提前考虑了第三次作业的要求,可拓展性较强,直接沿用到了第三次作业。

第三次作业重构了第二次作业的化简框架,类的复杂度上升的同时化简功能也强大了不少。

总的来说,本次作业重构了1.5次,还算可以接受。

心得体会

本次作业让我充分理解了面向对象的优势,实现了从面向过程编程到面向对象编程的转变。

同时为了处理输入我还学会了一部分编译原理,理解了正则表达式状态机的搭建、LL(1)文法和递归下降法。

另外我也明白了框架设计的重要性,如果一开始框架没设计好,通常来讲进行功能拓展时总会感到强大的阻力,同时需要通过各种判定语句来处理各种情况,最后必然导致重构。

最后,本次作业也锻炼了我利用python、c++构造自动测频机来找自己BUG和hack别人的能力。

posted @ 2021-03-27 11:03  jxm2001  阅读(110)  评论(1)    收藏  举报