第一单元总结
HW1
UML图
代码结构分析
CLASS | code | 占比 | comment | 占比 | blanck | 占比 |
---|---|---|---|---|---|---|
ExprFactor.java | 38 | 0.7916667 | 0 | 0.0 | 10 | 0.208333 |
Factor.java | 4 | 0.8000000 | 0 | 0.0 | 1 | 0.200000 |
Lexer.java | 80 | 0.9411764 | 0 | 0.0 | 5 | 0.058821 |
Main.java | 17 | 0.5862068 | 11 | 0.379310 | 1 | 0.034482 |
NumberFactor.java | 17 | 0.8095238 | 0 | 0.0 | 4 | 0.190476 |
Parser.java | 98 | 0.9074074 | 4 | 0.037037 | 6 | 0.050000 |
PolyItem.java | 44 | 0.8000000 | 0 | 0.0 | 11 | 0.200000 |
Polynomial.java | 165 | 0.6680161 | 67 | 0.271255 | 15 | 0.060728 |
PowerFactor.java | 31 | 0.8611111 | 0 | 0.0 | 5 | 0.138896 |
Term.java | 42 | 0.8235294 | 0 | 0.0 | 9 | 0.176470 |
method | cogC | ev(G) | iv(G) | v(G) |
---|---|---|---|---|
ExprFactor.addTerm(Term) | 0.0 | 1.0 | 1.0 | 1.0 |
ExprFactor.ExprFactor() | 0.0 | 1.0 | 1.0 | 1.0 |
ExprFactor.ExprFactor(BigInteger, ArrayList) | 0.0 | 1.0 | 1.0 | 1.0 |
ExprFactor.makePolynomial() | 1.0 | 1.0 | 2.0 | 2.0 |
ExprFactor.makePolynomials() | 0.0 | 1.0 | 1.0 | 1.0 |
ExprFactor.myToString() | 1.0 | 1.0 | 2.0 | 2.0 |
ExprFactor.setIndex(BigInteger) | 0.0 | 1.0 | 1.0 | 1.0 |
Lexer.getNum() | 7.0 | 3.0 | 6.0 | 6.0 |
Lexer.Lexer(String) | 0.0 | 1.0 | 1.0 | 1.0 |
Lexer.next() | 24.0 | 2.0 | 9.0 | 19.0 |
Lexer.peek() | 0.0 | 1.0 | 1.0 | 1.0 |
Main.main(String[]) | 0.0 | 1.0 | 1.0 | 1.0 |
NumberFactor.makePolynomial() | 0.0 | 1.0 | 1.0 | 1.0 |
NumberFactor.myToString() | 0.0 | 1.0 | 1.0 | 1.0 |
NumberFactor.NumberFactor(BigInteger) | 0.0 | 1.0 | 1.0 | 1.0 |
Parser.parseExpr() | 4.0 | 1.0 | 3.0 | 4.0 |
Parser.parseFactor() | 18.0 | 4.0 | 10.0 | 10.0 |
Parser.Parser(Lexer) | 0.0 | 1.0 | 1.0 | 1.0 |
Parser.parseTerm() | 3.0 | 1.0 | 4.0 | 4.0 |
PolyItem.getCoefficient() | 0.0 | 1.0 | 1.0 | 1.0 |
PolyItem.getExponentX() | 0.0 | 1.0 | 1.0 | 1.0 |
PolyItem.getExponentY() | 0.0 | 1.0 | 1.0 | 1.0 |
PolyItem.getExponentZ() | 0.0 | 1.0 | 1.0 | 1.0 |
PolyItem.PolyItem() | 0.0 | 1.0 | 1.0 | 1.0 |
PolyItem.PolyItem(BigInteger, BigInteger, BigInteger, BigInteger) | 0.0 | 1.0 | 1.0 | 1.0 |
PolyItem.setCoefficient(BigInteger) | 0.0 | 1.0 | 1.0 | 1.0 |
PolyItem.setExponentX(BigInteger) | 0.0 | 1.0 | 1.0 | 1.0 |
PolyItem.setExponentY(BigInteger) | 0.0 | 1.0 | 1.0 | 1.0 |
PolyItem.setExponentZ(BigInteger) | 0.0 | 1.0 | 1.0 | 1.0 |
Polynomial.addPolyItem(PolyItem) | 0.0 | 1.0 | 1.0 | 1.0 |
Polynomial.addPolynomial(Polynomial, Polynomial) | 2.0 | 1.0 | 3.0 | 3.0 |
Polynomial.expandPolys(Polynomial, BigInteger) | 4.0 | 2.0 | 3.0 | 3.0 |
Polynomial.getPolyItems() | 0.0 | 1.0 | 1.0 | 1.0 |
Polynomial.mergePolys(ArrayList) | 6.0 | 1.0 | 4.0 | 4.0 |
Polynomial.multiPolyItems(Polynomial, Polynomial) | 3.0 | 1.0 | 3.0 | 3.0 |
Polynomial.myToString() | 1.0 | 1.0 | 2.0 | 2.0 |
Polynomial.Polynomial() | 0.0 | 1.0 | 1.0 | 1.0 |
Polynomial.Polynomial(ArrayList) | 0.0 | 1.0 | 1.0 | 1.0 |
Polynomial.samePolyItem(PolyItem, PolyItem) | 1.0 | 1.0 | 3.0 | 3.0 |
Polynomial.setPolyItems(ArrayList) | 0.0 | 1.0 | 1.0 | 1.0 |
Polynomial.toString() | 38.0 | 3.0 | 10.0 | 17.0 |
PowerFactor.makePolynomial() | 3.0 | 1.0 | 3.0 | 3.0 |
PowerFactor.myToString() | 0.0 | 1.0 | 1.0 | 1.0 |
PowerFactor.PowerFactor(BigInteger, String) | 0.0 | 1.0 | 1.0 | 1.0 |
Term.addFactors(Factor) | 0.0 | 1.0 | 1.0 | 1.0 |
Term.makePolynomial() | 2.0 | 1.0 | 3.0 | 3.0 |
Term.myToString() | 1.0 | 1.0 | 2.0 | 2.0 |
Term.setPositiveOrNegative(int) | 0.0 | 1.0 | 1.0 | 1.0 |
Term.Term() | 0.0 | 1.0 | 1.0 | 1.0 |
Term.Term(int, ArrayList) | 0.0 | 1.0 | 1.0 | 1.0 |
Average | 2.38 | 1.18 | 2.1 | 2.46 |
架构体会
构建表达式树
第一次开始从0到这么大的代码量的架构设计,第一次设计的时候再看完了一些学长的架构后不明所以,后来经过和同学之间的交流最后逐渐明白了往届学长的一些设计的精妙,开始进行架构。
本文仍然采用递归下降法,将一个表达式分为了表达式 -> 项 -> 因子 ,而因子包括表达式因子 、数字因子 、幂因子
但是本人最开始遇到的难题就是因子内其实还是有一个表达式的,这样想容易陷入到了无限递归的循环陷阱之中。但其实,我们一定可以找到一个最终的项,而且它里面包含的有且只有数字因子和幂因子。
于是我们设计的时候可以把每一个因子都设计一个类.
由于我们可以进行抽象,所以我们很自然地把表达式、幂函数、数字这三个类统一用一个接口来实现,这么做是合乎直觉的,这也为后面的项 后面的设计提供了方便
表达式因子里面包含了一个指数和一个Arraylist,Arraylist里面的对象就是因子,意思就是表达式=项±项±项±......
项 里面包含了一个ArrayList,因为我们之前已经说了把三个因子统一为一个名为Factor的接口,所以我们很自然地把ArrayList里面的对象定义为Factor。意思就是项=因子*因子*因子*...
因子 类中因为前面已经说过了表达式因子,然后我们只需要再定义数字因子和幂因子。注意数字因子最好用BigInteger类来定义,幂因子包含了一个String类作为名字,以及一个BigInteger类作为指数。
构建标准项
由于最终的表达式一定是以多个a*x**b*y**c*z**d相加的形式存在,所以直接定义PolyItem来表示,同时定义Polynomial对PolyItem进行存储和化简,第一次作业本身只涉及底数相同的PolyItem的化简,所以直接将指数作为Hashmap的键,只要指数相同就直接化简即可。为了简化答案,可以再指数以及系数上进行特判。
这里有一个个人认为比较困难的问题是,如何进行两个表达式的乘积。本人的做法是对于每个表达式都搞出一个Polynomial,然后直接进行表达式的乘积,具体做法就是二次循环,然后再设计一个merge()方法,化简输出
输出
输出看似不难,但是很容易出bug,具体的做法比如说当构建好了Polynomial后直接写一个toString()方法。我在这里有一个bug,我直接特判了当最后的字符串中出现了1*的情况,我直接删去了,这种会导致21*x变成了2x。这也是我强测出现的bug
bug分析
强测bug
第一次出现的bug是在输出的时候过于偷懒,直接在main()方法中直接特判1*x的情况,正确的做法是将+1* 和-1* 的情况进行特判,但是其实这种跟人感觉也不是很好的方法,最佳的方法应该是在Polynomial类中写好toString()方法
出现了bug的方法代码行和圈复杂度
个人分析认为其实出现bug的原因就说我在Polynomial类中写的toString方法特别糟糕,用了过多的特判导致最好超过60行的限制了不得不把一些内容放在main里面
与Average对比,可以看见复杂度确实非常高,因此在之后的代码中应该进行改进
他人的bug
本次互测使用了(0)** 0这个数据点hack到了两位同学的bug
同时使用了我自己的bug 21*x这个bug也成功hack到一位同学,可以发现同学没有对(0)**0特判,也在输出优化的时候过于大意
HW2
UML图
代码架构分析
CLASS | Line | 占比 | comment | 占比 | blanck | 占比 |
---|---|---|---|---|---|---|
ExprFactor.java | 53 | 0.8153 | 0 | 0.0 | 12 | 0.18461 |
Factor.java | 4 | 0.8 | 0 | 0.0 | 1 | 0.2 |
FuncParser.java | 3 | 0.75 | 0 | 0.0 | 1 | 0.25 |
Lexer.java | 82 | 0.7884 | 15 | 0.1442 | 7 | 0.06730 |
Main.java | 24 | 0.6153 | 13 | 0.3333 | 2 | 0.05128 |
NumberFactor.java | 20 | 0.8334 | 0 | 0.0 | 4 | 0.16667 |
Parser.java | 165 | 0.8049 | 26 | 0.1268 | 14 | 0.06829 |
PolyItem.java | 146 | 0.6822 | 43 | 0.2009 | 25 | 0.11682 |
Polynomial.java | 172 | 0.4686 | 172 | 0.4686 | 23 | 0.06267 |
PowerFactor.java | 34 | 0.8717 | 0 | 0.0 | 5 | 0.12821 |
SelfFuncFactor.java | 56 | 0.5773 | 24 | 0.2472 | 17 | 0.17526 |
SelfFuncItem.java | 18 | 0.75 | 0 | 0.0 | 6 | 0.25 |
Term.java | 48 | 0.8275 | 0 | 0.0 | 10 | 0.17241 |
TriangleFactor.java | 50 | 0.7576 | 6 | 0.0909 | 10 | 0.15151 |
method | cogC | ev(G) | iv(G) | v(G) |
---|---|---|---|---|
Derivative.differentiateExpr(ExprFactor) | 1.0 | 1.0 | 2.0 | 2.0 |
Derivative.differentiateTerm(Term) | 0.0 | 1.0 | 1.0 | 1.0 |
Derivative.makePolynomial() | 0.0 | 1.0 | 1.0 | 1.0 |
Derivative.myToString() | 0.0 | 1.0 | 1.0 | 1.0 |
ExprFactor.addTerm(Term) | 0.0 | 1.0 | 1.0 | 1.0 |
ExprFactor.ExprFactor() | 0.0 | 1.0 | 1.0 | 1.0 |
ExprFactor.ExprFactor(BigInteger, ArrayList) | 0.0 | 1.0 | 1.0 | 1.0 |
ExprFactor.getIndex() | 0.0 | 1.0 | 1.0 | 1.0 |
ExprFactor.getTerms() | 0.0 | 1.0 | 1.0 | 1.0 |
ExprFactor.makePolynomial() | 2.0 | 2.0 | 3.0 | 3.0 |
ExprFactor.makePolynomials() | 0.0 | 1.0 | 1.0 | 1.0 |
ExprFactor.myToString() | 1.0 | 1.0 | 2.0 | 2.0 |
ExprFactor.setIndex(BigInteger) | 0.0 | 1.0 | 1.0 | 1.0 |
Lexer.getNum() | 2.0 | 1.0 | 3.0 | 3.0 |
Lexer.getPos() | 0.0 | 1.0 | 1.0 | 1.0 |
Lexer.Lexer(String) | 0.0 | 1.0 | 1.0 | 1.0 |
Lexer.next() | 27.0 | 2.0 | 13.0 | 23.0 |
Lexer.peek() | 0.0 | 1.0 | 1.0 | 1.0 |
Main.main(String[]) | 1.0 | 1.0 | 2.0 | 2.0 |
NumberFactor.makePolynomial() | 0.0 | 1.0 | 1.0 | 1.0 |
NumberFactor.myToString() | 0.0 | 1.0 | 1.0 | 1.0 |
NumberFactor.NumberFactor(BigInteger) | 0.0 | 1.0 | 1.0 | 1.0 |
Parser.parseDerivative() | 0.0 | 1.0 | 1.0 | 1.0 |
Parser.parseExpr() | 4.0 | 1.0 | 3.0 | 4.0 |
Parser.parseFactor() | 17.0 | 6.0 | 13.0 | 13.0 |
Parser.parsePower() | 3.0 | 1.0 | 3.0 | 3.0 |
Parser.Parser(Lexer) | 0.0 | 1.0 | 1.0 | 1.0 |
Parser.Parser(String) | 0.0 | 1.0 | 1.0 | 1.0 |
Parser.parseSelfFuncFactor() | 5.0 | 1.0 | 5.0 | 5.0 |
Parser.parseTerm() | 3.0 | 1.0 | 4.0 | 4.0 |
Parser.parseTriangleFactor() | 3.0 | 1.0 | 3.0 | 3.0 |
PolyItem.clone() | 1.0 | 1.0 | 1.0 | 2.0 |
PolyItem.getCoefficient() | 0.0 | 1.0 | 1.0 | 1.0 |
PolyItem.getCos() | 0.0 | 1.0 | 1.0 | 1.0 |
PolyItem.getExponentX() | 0.0 | 1.0 | 1.0 | 1.0 |
PolyItem.getExponentY() | 0.0 | 1.0 | 1.0 | 1.0 |
PolyItem.getExponentZ() | 0.0 | 1.0 | 1.0 | 1.0 |
PolyItem.getSin() | 0.0 | 1.0 | 1.0 | 1.0 |
PolyItem.ifEqual(PolyItem, PolyItem) | 0.0 | 1.0 | 1.0 | 1.0 |
PolyItem.PolyItem() | 0.0 | 1.0 | 1.0 | 1.0 |
PolyItem.PolyItem(BigInteger, BigInteger, BigInteger, BigInteger, HashMap, HashMap) | 0.0 | 1.0 | 1.0 | 1.0 |
PolyItem.setCoefficient(BigInteger) | 0.0 | 1.0 | 1.0 | 1.0 |
PolyItem.setExponentX(BigInteger) | 0.0 | 1.0 | 1.0 | 1.0 |
PolyItem.setExponentY(BigInteger) | 0.0 | 1.0 | 1.0 | 1.0 |
PolyItem.setExponentZ(BigInteger) | 0.0 | 1.0 | 1.0 | 1.0 |
PolyItem.toString() | 29.0 | 2.0 | 15.0 | 16.0 |
Polynomial.addPolyItem(PolyItem) | 0.0 | 1.0 | 1.0 | 1.0 |
Polynomial.addPolynomial(Polynomial, Polynomial) | 2.0 | 1.0 | 3.0 | 3.0 |
Polynomial.clone() | 1.0 | 1.0 | 1.0 | 2.0 |
Polynomial.expandPolys(Polynomial, BigInteger) | 4.0 | 2.0 | 3.0 | 3.0 |
Polynomial.getPolyItems() | 0.0 | 1.0 | 1.0 | 1.0 |
Polynomial.mergePolys(ArrayList) | 6.0 | 1.0 | 4.0 | 4.0 |
Polynomial.multiPolyItems(Polynomial, Polynomial) | 15.0 | 1.0 | 7.0 | 7.0 |
Polynomial.myToString() | 1.0 | 1.0 | 2.0 | 2.0 |
Polynomial.plusPolyItem(Polynomial, PolyItem) | 0.0 | 1.0 | 1.0 | 1.0 |
Polynomial.Polynomial() | 0.0 | 1.0 | 1.0 | 1.0 |
Polynomial.Polynomial(ArrayList) | 0.0 | 1.0 | 1.0 | 1.0 |
Polynomial.samePolyItem(PolyItem, PolyItem) | 1.0 | 1.0 | 5.0 | 5.0 |
Polynomial.setPolyItems(ArrayList) | 0.0 | 1.0 | 1.0 | 1.0 |
Polynomial.toString() | 3.0 | 2.0 | 3.0 | 4.0 |
PowerFactor.makePolynomial() | 3.0 | 1.0 | 3.0 | 3.0 |
PowerFactor.myToString() | 0.0 | 1.0 | 1.0 | 1.0 |
PowerFactor.PowerFactor(BigInteger, String) | 0.0 | 1.0 | 1.0 | 1.0 |
SelfFuncFactor.getDefFunctionF() | 0.0 | 1.0 | 1.0 | 1.0 |
SelfFuncFactor.getDefFunctionG() | 0.0 | 1.0 | 1.0 | 1.0 |
SelfFuncFactor.getDefFunctionH() | 0.0 | 1.0 | 1.0 | 1.0 |
SelfFuncFactor.getDefinitionF() | 0.0 | 1.0 | 1.0 | 1.0 |
SelfFuncFactor.getDefinitionG() | 0.0 | 1.0 | 1.0 | 1.0 |
SelfFuncFactor.getDefinitionH() | 0.0 | 1.0 | 1.0 | 1.0 |
SelfFuncFactor.makePolynomial() | 0.0 | 1.0 | 1.0 | 1.0 |
SelfFuncFactor.myToString() | 0.0 | 1.0 | 1.0 | 1.0 |
SelfFuncFactor.setDefFunctionF(SelfFuncItem) | 0.0 | 1.0 | 1.0 | 1.0 |
SelfFuncFactor.setDefFunctionG(SelfFuncItem) | 0.0 | 1.0 | 1.0 | 1.0 |
SelfFuncFactor.setDefFunctionH(SelfFuncItem) | 0.0 | 1.0 | 1.0 | 1.0 |
SelfFuncFactor.setDefinition(String, String) | 0.0 | 1.0 | 1.0 | 1.0 |
SelfFuncFactor.setFuncName(String) | 0.0 | 1.0 | 1.0 | 1.0 |
SelfFuncItem.subFunction1(String) | 0.0 | 1.0 | 1.0 | 1.0 |
SelfFuncItem.subFunction2(String, String) | 0.0 | 1.0 | 1.0 | 1.0 |
SelfFuncItem.subFunction3(String, String, String) | 0.0 | 1.0 | 1.0 | 1.0 |
Term.addFactors(Factor) | 0.0 | 1.0 | 1.0 | 1.0 |
Term.getFactors() | 0.0 | 1.0 | 1.0 | 1.0 |
Term.makePolynomial() | 2.0 | 1.0 | 3.0 | 3.0 |
Term.myToString() | 1.0 | 1.0 | 2.0 | 2.0 |
Term.setPositiveOrNegative(int) | 0.0 | 1.0 | 1.0 | 1.0 |
Term.Term() | 0.0 | 1.0 | 1.0 | 1.0 |
Term.Term(int, ArrayList) | 0.0 | 1.0 | 1.0 | 1.0 |
TriangleFactor.getInnerFactor() | 0.0 | 1.0 | 1.0 | 1.0 |
TriangleFactor.ifEqual(TriangleFactor, TriangleFactor) | 0.0 | 1.0 | 1.0 | 1.0 |
TriangleFactor.makePolynomial() | 9.0 | 4.0 | 6.0 | 6.0 |
TriangleFactor.myToString() | 0.0 | 1.0 | 1.0 | 1.0 |
TriangleFactor.TriangleFactor(String, BigInteger, Factor) | 0.0 | 1.0 | 1.0 | 1.0 |
Total | 147.0 | 104.0 | 179.0 | 194.0 |
Average | 1.6153 | 1.1428 | 1.9670 | 2.131 |
架构体验
三角函数
本次新增了三角函数,出于和HW1一样的思维惯性,我们很自然的直接新定义了一个三角函数类,其中包含了一个String类的name,一个Factor类来抽象其中的式子,并且还有一个指数。在构建表达式树的时候我们并没有多少的区别,只不过在构建标准项的时候多了两个Hashmap来将三角函数对应的式子和外部的指数联系起来
自定义函数
本次还新增了一个自定义函数,由于并没有较好的方法,我直接采用在最开始的时候先解析并且构建好我们的三角函数的表达式,并且把它作为字符串的形式直接存储为一个static变量存储在一个SelfFuncFactor类中。
自定义函数的一些小处理
由于题目指出自定义函数在定义的时候可以出现f(y,x)这类的形式,于是乎,我们在存储函数定义式的时候做了一些小处理,我们直接通过文本替换,把第一个变量在定义式中直接替换成“X",将第二个变量直接替换成”Y",将第三个变量直接替换成“Z",这样就不用再判断自变量的顺序了。在后来的解析式中,我们直接文本替换,然后再进行parse
bug分析
自己的bug
本次在强测中没有bug,但是互测的时候出现了一个bug,sin(0)**0由于在之前优化的时候直接特判,导致结果变成了0
出现了bug的方法代码行和圈复杂度
经过自己的分析,我发现这个bug纯粹是优化处理的时候忘记特判了,因此我们在每次的优化中,对于每一种特判都要好好想清楚这个特判是否有一些特例
hack他人
同样的在sin(0)**0这个bug中也成功hack了一位同学,本次测试中采用了评测机评测,但是在评测的过程中由于给出的例子不够经典和随机,并没有测出别人的bug,反倒是经过同学的提醒才想到sin(0)**0这个特例,但同时也很悲伤地发现自己也错了(doge
HW3
UML图
代码结构分析
Class | line | 占比 | comment | 占比 | blanck | 占比 |
---|---|---|---|---|---|---|
ExprFactor.java | 109 | 0.872 | 2 | 0.016 | 14 | 0.112 |
Factor.java | 7 | 0.6363 | 0 | 0.0 | 4 | 0.3636 |
FuncParser.java | 3 | 0.75 | 0 | 0.0 | 1 | 0.25 |
Lexer.java | 85 | 0.8018 | 15 | 0.1415 | 6 | 0.0566 |
Main.java | 27 | 0.6136 | 14 | 0.3181 | 3 | 0.0682 |
NumberFactor.java | 49 | 0.8167 | 2 | 0.0333 | 9 | 0.15 |
Parser.java | 176 | 0.7753 | 36 | 0.1586 | 15 | 0.0660 |
PolyItem.java | 146 | 0.6822 | 43 | 0.2009 | 25 | 0.1168 |
Polynomial.java | 172 | 0.4687 | 172 | 0.4687 | 23 | 0.0627 |
PowerFactor.java | 82 | 0.8542 | 3 | 0.03125 | 11 | 0.1146 |
SelfFuncFactor.java | 97 | 0.6510 | 30 | 0.20134 | 22 | 0.1476 |
SelfFuncItem.java | 18 | 0.75 | 0 | 0.0 | 6 | 0.25 |
Term.java | 85 | 0.8333 | 3 | 0.02941 | 14 | 0.1372 |
TriangleFactor.java | 130 | 0.8552 | 8 | 0.05263 | 14 | 0.0921 |
method | cogC | ev(G) | iv(G) | v(G) |
---|---|---|---|---|
ExprFactor.addTerm(Term) | 0.0 | 1.0 | 1.0 | 1.0 |
ExprFactor.clone() | 1.0 | 1.0 | 1.0 | 2.0 |
ExprFactor.differentiateFactor(String) | 6.0 | 2.0 | 6.0 | 6.0 |
ExprFactor.ExprFactor() | 0.0 | 1.0 | 1.0 | 1.0 |
ExprFactor.ExprFactor(BigInteger, ArrayList) | 0.0 | 1.0 | 1.0 | 1.0 |
ExprFactor.getIndex() | 0.0 | 1.0 | 1.0 | 1.0 |
ExprFactor.getTerms() | 0.0 | 1.0 | 1.0 | 1.0 |
ExprFactor.makePolynomial() | 2.0 | 2.0 | 3.0 | 3.0 |
ExprFactor.myToString() | 1.0 | 1.0 | 2.0 | 2.0 |
ExprFactor.setIndex(BigInteger) | 0.0 | 1.0 | 1.0 | 1.0 |
Lexer.getNum() | 2.0 | 1.0 | 3.0 | 3.0 |
Lexer.getPos() | 0.0 | 1.0 | 1.0 | 1.0 |
Lexer.Lexer(String) | 0.0 | 1.0 | 1.0 | 1.0 |
Lexer.next() | 33.0 | 2.0 | 15.0 | 26.0 |
Lexer.peek() | 0.0 | 1.0 | 1.0 | 1.0 |
Main.main(String[]) | 1.0 | 1.0 | 2.0 | 2.0 |
NumberFactor.clone() | 1.0 | 1.0 | 1.0 | 2.0 |
NumberFactor.differentiateFactor(String) | 0.0 | 1.0 | 1.0 | 1.0 |
NumberFactor.getNumber() | 0.0 | 1.0 | 1.0 | 1.0 |
NumberFactor.makePolynomial() | 0.0 | 1.0 | 1.0 | 1.0 |
NumberFactor.myToString() | 0.0 | 1.0 | 1.0 | 1.0 |
NumberFactor.NumberFactor(BigInteger) | 0.0 | 1.0 | 1.0 | 1.0 |
Parser.parseDerivative() | 0.0 | 1.0 | 1.0 | 1.0 |
Parser.parseDerivativeFactor() | 3.0 | 1.0 | 2.0 | 3.0 |
Parser.parseExpr() | 4.0 | 1.0 | 3.0 | 4.0 |
Parser.parseFactor() | 19.0 | 7.0 | 16.0 | 16.0 |
Parser.parsePower() | 3.0 | 1.0 | 3.0 | 3.0 |
Parser.Parser(Lexer) | 0.0 | 1.0 | 1.0 | 1.0 |
Parser.Parser(String) | 0.0 | 1.0 | 1.0 | 1.0 |
Parser.parseSelfFuncFactor() | 2.0 | 1.0 | 3.0 | 3.0 |
Parser.parseTerm() | 3.0 | 1.0 | 4.0 | 4.0 |
Parser.parseTriangleFactor() | 3.0 | 1.0 | 3.0 | 3.0 |
PolyItem.clone() | 1.0 | 1.0 | 1.0 | 2.0 |
PolyItem.getCoefficient() | 0.0 | 1.0 | 1.0 | 1.0 |
PolyItem.getCos() | 0.0 | 1.0 | 1.0 | 1.0 |
PolyItem.getExponentX() | 0.0 | 1.0 | 1.0 | 1.0 |
PolyItem.getExponentY() | 0.0 | 1.0 | 1.0 | 1.0 |
PolyItem.getExponentZ() | 0.0 | 1.0 | 1.0 | 1.0 |
PolyItem.getSin() | 0.0 | 1.0 | 1.0 | 1.0 |
PolyItem.ifEqual(PolyItem, PolyItem) | 0.0 | 1.0 | 1.0 | 1.0 |
PolyItem.PolyItem() | 0.0 | 1.0 | 1.0 | 1.0 |
PolyItem.PolyItem(BigInteger, BigInteger, BigInteger, BigInteger, HashMap, HashMap) | 0.0 | 1.0 | 1.0 | 1.0 |
PolyItem.setCoefficient(BigInteger) | 0.0 | 1.0 | 1.0 | 1.0 |
PolyItem.setExponentX(BigInteger) | 0.0 | 1.0 | 1.0 | 1.0 |
PolyItem.setExponentY(BigInteger) | 0.0 | 1.0 | 1.0 | 1.0 |
PolyItem.setExponentZ(BigInteger) | 0.0 | 1.0 | 1.0 | 1.0 |
PolyItem.toString() | 29.0 | 2.0 | 15.0 | 16.0 |
Polynomial.addPolyItem(PolyItem) | 0.0 | 1.0 | 1.0 | 1.0 |
Polynomial.addPolynomial(Polynomial, Polynomial) | 2.0 | 1.0 | 3.0 | 3.0 |
Polynomial.clone() | 1.0 | 1.0 | 1.0 | 2.0 |
Polynomial.expandPolys(Polynomial, BigInteger) | 4.0 | 2.0 | 3.0 | 3.0 |
Polynomial.getPolyItems() | 0.0 | 1.0 | 1.0 | 1.0 |
Polynomial.mergePolys(ArrayList) | 6.0 | 1.0 | 4.0 | 4.0 |
Polynomial.multiPolyItems(Polynomial, Polynomial) | 15.0 | 1.0 | 7.0 | 7.0 |
Polynomial.myToString() | 1.0 | 1.0 | 2.0 | 2.0 |
Polynomial.plusPolyItem(Polynomial, PolyItem) | 0.0 | 1.0 | 1.0 | 1.0 |
Polynomial.Polynomial() | 0.0 | 1.0 | 1.0 | 1.0 |
Polynomial.Polynomial(ArrayList) | 0.0 | 1.0 | 1.0 | 1.0 |
Polynomial.samePolyItem(PolyItem, PolyItem) | 1.0 | 1.0 | 5.0 | 5.0 |
Polynomial.setPolyItems(ArrayList) | 0.0 | 1.0 | 1.0 | 1.0 |
Polynomial.toString() | 3.0 | 2.0 | 3.0 | 4.0 |
PowerFactor.clone() | 1.0 | 1.0 | 1.0 | 2.0 |
PowerFactor.differentiateFactor(String) | 4.0 | 3.0 | 3.0 | 3.0 |
PowerFactor.getIndex() | 0.0 | 1.0 | 1.0 | 1.0 |
PowerFactor.getName() | 0.0 | 1.0 | 1.0 | 1.0 |
PowerFactor.makePolynomial() | 3.0 | 1.0 | 3.0 | 3.0 |
PowerFactor.myToString() | 0.0 | 1.0 | 1.0 | 1.0 |
PowerFactor.PowerFactor(BigInteger, String) | 0.0 | 1.0 | 1.0 | 1.0 |
SelfFuncFactor.clone() | 1.0 | 1.0 | 1.0 | 2.0 |
SelfFuncFactor.differentiateFactor(String) | 0.0 | 1.0 | 1.0 | 1.0 |
SelfFuncFactor.getDefFunctionF() | 0.0 | 1.0 | 1.0 | 1.0 |
SelfFuncFactor.getDefFunctionG() | 0.0 | 1.0 | 1.0 | 1.0 |
SelfFuncFactor.getDefFunctionH() | 0.0 | 1.0 | 1.0 | 1.0 |
SelfFuncFactor.getDefinitionF() | 0.0 | 1.0 | 1.0 | 1.0 |
SelfFuncFactor.getDefinitionG() | 0.0 | 1.0 | 1.0 | 1.0 |
SelfFuncFactor.getDefinitionH() | 0.0 | 1.0 | 1.0 | 1.0 |
SelfFuncFactor.getFunctionList() | 0.0 | 1.0 | 1.0 | 1.0 |
SelfFuncFactor.makePolynomial() | 0.0 | 1.0 | 1.0 | 1.0 |
SelfFuncFactor.myToString() | 0.0 | 1.0 | 1.0 | 1.0 |
SelfFuncFactor.setDefFunctionF(SelfFuncItem) | 0.0 | 1.0 | 1.0 | 1.0 |
SelfFuncFactor.setDefFunctionG(SelfFuncItem) | 0.0 | 1.0 | 1.0 | 1.0 |
SelfFuncFactor.setDefFunctionH(SelfFuncItem) | 0.0 | 1.0 | 1.0 | 1.0 |
SelfFuncFactor.setDefinition(String, String) | 9.0 | 1.0 | 5.0 | 7.0 |
SelfFuncFactor.setFuncName(String) | 0.0 | 1.0 | 1.0 | 1.0 |
SelfFuncItem.subFunction1(String) | 0.0 | 1.0 | 1.0 | 1.0 |
SelfFuncItem.subFunction2(String, String) | 0.0 | 1.0 | 1.0 | 1.0 |
SelfFuncItem.subFunction3(String, String, String) | 0.0 | 1.0 | 1.0 | 1.0 |
Term.addFactors(Factor) | 0.0 | 1.0 | 1.0 | 1.0 |
Term.clone() | 1.0 | 1.0 | 1.0 | 2.0 |
Term.differentiateTerm(String) | 1.0 | 1.0 | 2.0 | 2.0 |
Term.getFactors() | 0.0 | 1.0 | 1.0 | 1.0 |
Term.makePolynomial() | 2.0 | 1.0 | 3.0 | 3.0 |
Term.myToString() | 1.0 | 1.0 | 2.0 | 2.0 |
Term.setPositiveOrNegative(int) | 0.0 | 1.0 | 1.0 | 1.0 |
Term.Term() | 0.0 | 1.0 | 1.0 | 1.0 |
Term.Term(int, ArrayList) | 0.0 | 1.0 | 1.0 | 1.0 |
TriangleFactor.clone() | 1.0 | 1.0 | 1.0 | 2.0 |
TriangleFactor.differentiateFactor(String) | 15.0 | 4.0 | 8.0 | 8.0 |
TriangleFactor.getInnerFactor() | 0.0 | 1.0 | 1.0 | 1.0 |
TriangleFactor.ifEqual(TriangleFactor, TriangleFactor) | 0.0 | 1.0 | 1.0 | 1.0 |
TriangleFactor.makePolynomial() | 9.0 | 4.0 | 6.0 | 6.0 |
TriangleFactor.myToString() | 0.0 | 1.0 | 1.0 | 1.0 |
TriangleFactor.TriangleFactor(String, BigInteger, Factor) | 0.0 | 1.0 | 1.0 | 1.0 |
Total | 195.0 | 123.0 | 213.0 | 238.0 |
Average | 1.8932 | 1.1941 | 2.0679 | 2.3106 |
####
架构体会
本次架构出现了求导,同时可以多层嵌套括号,但是由于之前的架构非常坚挺,所以本次作业反而个人感觉成了最简单的一次。这也提醒我们第一次的基础架构是多么重要
在本次架构中,我们遇到了一个问题就是,在求导的时候使先构建标准多项式再求导,还是先求导再构建标准多项式。我个人的做法是先求导再统一构建标准多项式。这么做的原因是我发现求导法则依然有表达式那样的层序结构
求导的层序结构
我们先抽象一个表达式求导,我们假定了一个统一的方法为求导。
面对表达式的求导,我们只需要输入一个Expression类的表达式,然后返回一个Expression类的表达式。我们很清楚其实就是表达式中所有项的求导结果或加或相减即可,甚至于如果把每一项的正负号融合在了项这个类中的话,我们只需要无脑对每个项进行求导就行了。具体操作就是去除表达式中的每个项,然后对每个项求导再放回到ArrayList中。但是需要注意的是对于有指数的情况,一定要记得还要再乘以一个指数和一个原本的项。
面对项的求导,我们对乘法法则进行推广的话,很容易发现
对于项中的每一项,我们先克隆一个,然后只需要把第n个从List中取出来,求导好再塞回去,这么重复n次,然后把它们加起来,所以项的求导本质上返回的是一个表达式。
对于因子的求导,只需要对每个进行特判即可。注意返回值最好设为Factor,因为有些因子求导了是还是自己的因子,但是有一些(例如x**2)求导了变成了2*x,那还不如把他搞成一个表达式因子,只不过这样的话会比较亏时间。
bug分析
本次并没有出现强测和互测阶段的bug。
hack他人bug
在测试的时候发现有一位同学的当指数过大,比如((((x+1)**2)**2)**2)**2这样的式子,就会直接爆堆。我猜测是优化过多导致new的对象过多了的原因。
心得体会
这是综合了三次作业最后的心得体会。
首先,一个良好的架构是非常重要的,可以说,第一次作业中如果话下足够的时间线想好正确且可扩展的架构,就可以在之后的作业中事半功倍。我第一次作业是在周天凌晨完成的,而第二次作业因为第一次架构成功的原因成功在周六就完成了,第三次作业由于扩展性,求导甚至没有做出任何的新的类的扩展,只是在几个Factor类中加上了求导的方法,在周四就完成了作业。由此可见,第一次作业正确的架构师有多么的重要。
其次,面对优化,做出正确的克隆能够对我们的性能分有一个质的提升。第一次作业性能分由于没有三角函数的出现所以性能分并不低。而我第二次作业的时候由于几乎没有任何优化,导致出现了好几个性能分为0的强测点。因此第三次作业进行了深克隆,对一些含有三角函数的式子进行了优化,于是性能分有了很大的提升,但是依然有很多可以提升的空间。
最后,做好测试也是至关重要的。因为有一个好舍友,所以我们能够在一起使用对拍器进行对拍,但是很不幸的是我第一次和第二次都出现了一些在优化上的错误,这些错误都是很愚蠢但是又很容易忽略的。但是第三次作业使用了鹿同学的评测机,第三次作业就顺利通过了所有强测和互测,由此可见,一个好的评测机是有多么的重要。当然,在互测阶段,hack别人的代码的时候,也可以快速使用对拍器或者评测机“速通”bug。但是,我最后发现的bug都是自己设计的一些比较“刁钻”的样例,这也侧面说明了评测机由于是随机构造的,所以可以更多地去试试人工方法。