佛系甜胖妮

导航

BUAA OO Unit1总结

BUAA OO Unit1总结

前言

  • 本次作业的目的是完成对一个形式化表达式的去括号并化简的处理。

  • 总结而言,本次作业个人完成的比较曲折,尤其是一开始没有理清架构就开始写代码,导致第二次作业完全推翻了第一次作业的架构,进行了一次非常搞心态的重构。第三次作业在第二次作业上迭代。

Homework1

设计要求

  • 单变量因子x的多项式去括号处理。

  • 第一次作业用的数据结构中栈的方法,用栈将形式化表达式转化为后缀表达式,在利用栈将后缀表达式计算并且化简。

  • 第一次作业下来,发现本算法几乎很难进行迭代,和面向对象的设计初衷相背离,更类似于面向过程,所以在第二次作业进行重构。

bug分析

  • 主要是关于符号处理上的bug。bug太多了,后来重构了...

Homework2

设计要求

  • 在第一次作业的基础上,第二次作业增添了自定义函数,求和函数,三角函数等新的元素,并且单变量x也扩展成了多变量x,y,z。

架构设计体验

  • uml图
    image
    根据指导书,我一共设置了三个类:

  • 表达式类(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在架构上没有很大差别,就是在化简方面做了添加了一些方法。

image

度量分析

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!
  • 希望可以尝试写一个评测机。
  • 这次作业对我有很大的帮助,总结了不少失败经验,也提高了心理承受能力,希望下一次作业可以对我好一点点,以一颗平静的心去面对吧。

posted on 2022-03-24 10:04  佛系甜胖妮²⁰²¹  阅读(176)  评论(3编辑  收藏  举报