BUAA OO Unit1总结
BUAA OO Unit1总结
前言
-
本次作业的目的是完成对一个形式化表达式的去括号并化简的处理。
-
总结而言,本次作业个人完成的比较曲折,尤其是一开始没有理清架构就开始写代码,导致第二次作业完全推翻了第一次作业的架构,进行了一次非常搞心态的重构。第三次作业在第二次作业上迭代。
Homework1
设计要求
-
单变量因子x的多项式去括号处理。
-
第一次作业用的数据结构中栈的方法,用栈将形式化表达式转化为后缀表达式,在利用栈将后缀表达式计算并且化简。
-
第一次作业下来,发现本算法几乎很难进行迭代,和面向对象的设计初衷相背离,更类似于面向过程,所以在第二次作业进行重构。
bug分析
- 主要是关于符号处理上的bug。bug太多了,后来重构了...
Homework2
设计要求
- 在第一次作业的基础上,第二次作业增添了自定义函数,求和函数,三角函数等新的元素,并且单变量x也扩展成了多变量x,y,z。
架构设计体验
-
uml图
根据指导书,我一共设置了三个类: -
表达式类(Expression)
-
项类(Term)
-
因子类(Factor)
- 常数因子(Const)
- 幂函数因子(PowF)
- 三角函数因子(Trifunc)
- 表达式因子(Expression)
整体思路
- Pre
- 预处理,去除多余的空格,制表符等
- Lexer
- 词法分析,将表达式分离成一个个词
- Parser
- 递归解析表达式,在解析过程中计算表达式(边解析边计算)
- Simplify
- 化简表达式,合并常数项等
细节处理
- 我认为一个很需要细节处理的点是符号问题
- 最后的处理方法:
- 第一个运算符一律被认作连接项与项的运算符
- 第二个运算符被认作项的符号
- 第三个运算符则为数字因子的正负号
度量分析
Class | OCavg | OCmax | WMC |
---|---|---|---|
Frustrum | 2 | 3 | 4 |
Lexer | 3.62 | 14 | 29 |
MainClass | 2 | 2 | 2 |
Parser | 5.44 | 12 | 49 |
Pre | 1.33 | 2 | 4 |
Simplify | 3.5 | 6 | 7 |
calculate.Multi | 4.5 | 18 | 36 |
calculate.Pow | 3 | 3 | 3 |
object.Const | 1 | 1 | 6 |
object.Expr | 2 | 6 | 14 |
object.Function | 1.6 | 10 | 24 |
object.PowF | 1.17 | 2 | 7 |
object.SumF | 2.5 | 13 | 20 |
object.Term | 1.57 | 4 | 11 |
object.TriFunc | 1.12 | 2 | 9 |
bug分析
- 本次hack的bug有点多,裂开了。主要是一些没有处理到位的地方,导致没有输出。
- bug1:在一开始输入自定义函数的定义式的时候,没有去除空格或制表符,导致了很大的bug。
- bug2:没有认真阅读指导书,对于三角函数的处理存在问题,导致了格式不匹配的bug。类似三角函数的因子只能是常数因子和幂函数因子,我的处理方式会让+2变成0+2,这个就导致了格式不匹配。
- bug3:在自定义函数中识别因子可能是三角函数带指数的因子,应该改为普适性更强的识别方法。
Homework3
因为homework2的bug有点多并且都一一解决了,所以hw3就显得没有那么坎坷。
设计要求
- 在第二次作业的基础上,扩展了三角函数的因子,并且支持函数嵌套。
架构设计体验
- uml图——和homework2在架构上没有很大差别,就是在化简方面做了添加了一些方法。
度量分析
Class | OCavg | OCmax | WMC |
---|---|---|---|
Frustrum | 2 | 3 | 4 |
Lexer | 3.62 | 14 | 29 |
MainClass | 2 | 2 | 2 |
Parser | 5.22 | 14 | 47 |
Pre | 1.33 | 2 | 4 |
Simplify | 6 | 15 | 42 |
calculate.Equal | 4.5 | 5 | 9 |
calculate.Multi | 4.5 | 18 | 36 |
calculate.Pow | 3 | 3 | 3 |
object.Const | 1.17 | 2 | 7 |
object.Expr | 1.78 | 6 | 16 |
object.Function | 1.6 | 10 | 24 |
object.PowF | 1.17 | 2 | 7 |
object.SumF | 3.9 | 18 | 39 |
object.Term | 1.57 | 4 | 11 |
object.TriFunc | 1.62 | 6 | 13 |
- 和第二次作业出现的问题类似。
Method | CogC | ev(G) | iv(G) | v(G) |
---|---|---|---|---|
Frustrum.analyze(String) | 2 | 1 | 3 | 3 |
Frustrum.getFunctions() | 0 | 1 | 1 | 1 |
Lexer.getCurToken() | 0 | 1 | 1 | 1 |
Lexer.getNumber() | 2 | 1 | 3 | 3 |
Lexer.getPow() | 4 | 1 | 7 | 7 |
Lexer.judgeMinus() | 4 | 1 | 3 | 4 |
Lexer.judgeMulti() | 2 | 1 | 2 | 2 |
Lexer.judgePlus() | 3 | 1 | 3 | 3 |
Lexer.next() | 20 | 2 | 13 | 16 |
Lexer.setInput(String) | 0 | 1 | 1 | 1 |
MainClass.main(String[]) | 1 | 1 | 2 | 2 |
Parser.parseCos() | 3 | 1 | 3 | 4 |
Parser.parseExpr() | 51 | 8 | 14 | 15 |
Parser.parseFactor() | 10 | 7 | 10 | 10 |
Parser.parseFunction() | 6 | 3 | 4 | 5 |
Parser.parseSin() | 3 | 1 | 3 | 4 |
Parser.parseSumF() | 12 | 1 | 7 | 7 |
Parser.parseTerm() | 8 | 1 | 5 | 5 |
Parser.setFrustrum(ArrayList |
0 | 1 | 1 | 1 |
Parser.setLexer(Lexer) | 0 | 1 | 1 | 1 |
Pre.deal() | 2 | 1 | 2 | 3 |
Pre.getInput() | 0 | 1 | 1 | 1 |
Pre.setInput(String) | 0 | 1 | 1 | 1 |
Simplify.getSimExpr() | 0 | 1 | 1 | 1 |
Simplify.multiConst() | 13 | 1 | 6 | 6 |
Simplify.multiPow() | 22 | 1 | 12 | 12 |
Simplify.plusConst() | 10 | 4 | 6 | 6 |
Simplify.removeZeroOne() | 43 | 5 | 15 | 15 |
Simplify.setRaw(Expr) | 0 | 1 | 1 | 1 |
Simplify.simple() | 0 | 1 | 1 | 1 |
calculate.Equal.factorEqual(Factor, Factor) | 12 | 5 | 4 | 8 |
calculate.Equal.termEqual(Term, Term) | 7 | 4 | 3 | 4 |
calculate.Multi.consexprMulti(Const, Expr) | 5 | 3 | 4 | 4 |
calculate.Multi.conspowMulti(Const, PowF) | 3 | 3 | 3 | 3 |
calculate.Multi.constriMulti(Const, TriFunc) | 3 | 3 | 3 | 3 |
calculate.Multi.exprMulti(Expr, Expr) | 3 | 1 | 3 | 3 |
calculate.Multi.facexprMulti(Factor, Expr) | 1 | 1 | 2 | 2 |
calculate.Multi.facfacMulti(Factor, Factor) | 0 | 1 | 1 | 1 |
calculate.Multi.factorMulti(Factor, Factor) | 36 | 18 | 18 | 34 |
calculate.Multi.termMulti(Term, Term) | 4 | 1 | 5 | 5 |
calculate.Pow.pow(Expr, int) | 2 | 2 | 3 | 3 |
object.Const.getIndex() | 0 | 1 | 1 | 1 |
object.Const.getNum() | 0 | 1 | 1 | 1 |
object.Const.getResult() | 2 | 2 | 2 | 2 |
object.Const.setIndex(int) | 0 | 1 | 1 | 1 |
object.Const.setNum(BigInteger) | 0 | 1 | 1 | 1 |
object.Const.toString() | 0 | 1 | 1 | 1 |
object.Expr.addFirstop(String) | 0 | 1 | 1 | 1 |
object.Expr.addFirstterm(Term) | 0 | 1 | 1 | 1 |
object.Expr.addOp(String) | 0 | 1 | 1 | 1 |
object.Expr.addTerm(Term) | 0 | 1 | 1 | 1 |
object.Expr.getOperators() | 0 | 1 | 1 | 1 |
object.Expr.getResult() | 12 | 6 | 6 | 6 |
object.Expr.getTerms() | 0 | 1 | 1 | 1 |
object.Expr.setIndex(int) | 0 | 1 | 1 | 1 |
object.Expr.toString() | 2 | 1 | 3 | 3 |
object.Function.getName() | 0 | 1 | 1 | 1 |
object.Function.getResExpr() | 0 | 1 | 1 | 1 |
object.Function.getResult() | 0 | 1 | 1 | 1 |
object.Function.replace() | 27 | 7 | 10 | 10 |
object.Function.setArgument1(String) | 0 | 1 | 1 | 1 |
object.Function.setArgument2(String) | 0 | 1 | 1 | 1 |
object.Function.setArgument3(String) | 0 | 1 | 1 | 1 |
object.Function.setF1(Factor) | 0 | 1 | 1 | 1 |
object.Function.setF2(Factor) | 0 | 1 | 1 | 1 |
object.Function.setF3(Factor) | 0 | 1 | 1 | 1 |
object.Function.setFuncExpr(Expr) | 0 | 1 | 1 | 1 |
object.Function.setIndex(int) | 0 | 1 | 1 | 1 |
object.Function.setName(String) | 0 | 1 | 1 | 1 |
object.Function.setResExpr(Expr) | 0 | 1 | 1 | 1 |
object.Function.toString() | 0 | 1 | 1 | 1 |
object.PowF.getArgument() | 0 | 1 | 1 | 1 |
object.PowF.getIndex() | 0 | 1 | 1 | 1 |
object.PowF.getResult() | 0 | 1 | 1 | 1 |
object.PowF.setArgument(String) | 0 | 1 | 1 | 1 |
object.PowF.setIndex(int) | 0 | 1 | 1 | 1 |
object.PowF.toString() | 1 | 1 | 2 | 2 |
object.SumF.creTri(TriFunc, BigInteger) | 9 | 6 | 6 | 6 |
object.SumF.createExpr(Expr, BigInteger) | 15 | 4 | 8 | 8 |
object.SumF.createfuncExpr() | 48 | 5 | 18 | 18 |
object.SumF.getFuncExpr() | 0 | 1 | 1 | 1 |
object.SumF.getResult() | 0 | 1 | 1 | 1 |
object.SumF.setFactor(Factor) | 0 | 1 | 1 | 1 |
object.SumF.setHigh(BigInteger) | 0 | 1 | 1 | 1 |
object.SumF.setIndex(int) | 0 | 1 | 1 | 1 |
object.SumF.setLow(BigInteger) | 0 | 1 | 1 | 1 |
object.SumF.toString() | 0 | 1 | 1 | 1 |
object.Term.addAllfactor(Term) | 0 | 1 | 1 | 1 |
object.Term.addFactor(Factor) | 0 | 1 | 1 | 1 |
object.Term.getFactors() | 0 | 1 | 1 | 1 |
object.Term.getOp() | 0 | 1 | 1 | 1 |
object.Term.getResult() | 6 | 4 | 4 | 4 |
object.Term.setOp(String) | 0 | 1 | 1 | 1 |
object.Term.toString() | 1 | 1 | 2 | 2 |
object.TriFunc.getFactor() | 0 | 1 | 1 | 1 |
object.TriFunc.getIndex() | 0 | 1 | 1 | 1 |
object.TriFunc.getName() | 0 | 1 | 1 | 1 |
object.TriFunc.getResult() | 0 | 1 | 1 | 1 |
object.TriFunc.setFactor(Factor) | 0 | 1 | 1 | 1 |
object.TriFunc.setIndex(int) | 0 | 1 | 1 | 1 |
object.TriFunc.setName(String) | 0 | 1 | 1 | 1 |
object.TriFunc.toString() | 8 | 1 | 6 | 6 |
- 方法复杂度分析:大部分方法复杂度都在可接受范围内,有部分超出了范围,希望下次可以改进。
bug分析
公测bug:
- bug1:作业三的三角函数里面可以带变量i,在sum函数替换的时候,因为没有增加这个功能生成的求和函数表达式中的i没有替换成常熟因子。
- 修改sumF类中的替换方法。
- bug2:当指数嵌套的时候,容易超时。
- 及时化简,防止有太多项导致超时。
- bug3:一个java语法的bug,两个对象不能直接用=赋值,这样的话两个对象就同步了,奇奇怪怪的修改一下不想改的变量。
互测bug:
-
本次hack被hack了六次,其中五个都是完全一致的bug(裂开)。
-
bug1:sum函数上下界问题,int型范围不够,应该改为BigInteger型。
sum(i,123456789123456780,123456789123456789,i)
-
bug2:在sum函数中替换生成新的表达式中,忘了添加operator,导致在toString方法中有问题,无法输出。
心得体会
- 建议在开始写代码之前一定要认真阅读指导书,不能因为心急就提前开始,以认真看懂指导书和有一个清晰架构为前提才能使后续的coding事半功倍。这次作业心态炸裂以及后续有很多bug出现的原因就是没有认真阅读指导书的细节,以及在没有清晰的架构之前就开始做无用的coding。
- 建议有一个文档记录自己的bug,这样对于debug的思路更有条理,而且对后续总结整理也有帮助。
- 多和身边的同学讨论讨论,可以有新的灵感,闭门造车是万万不可以的。
- 这次有一点点遗憾的地方,比如没有在化简上下功夫吧。导致我的性能分就很低,so sad!
- 希望可以尝试写一个评测机。
- 这次作业对我有很大的帮助,总结了不少失败经验,也提高了心理承受能力,希望下一次作业可以对我好一点点,以一颗平静的心去面对吧。