OO-第一单元-总结

yplqing 学生 2024-03-21 21:33:57

OO-第一单元-总结

第一次作业

对一个包含加、减、乘、乘方运算,包含单变量x,含有括号的表达式进行等价化简。

基本思路

表达式解析:核心思路——找到最后一个运算的运算符,据此二分处理;由于优先级:乘方>乘>[加减],先找最后一个运算的[加减],即最外层括号外、最右边的[加减],然后找最后一个运算的[乘],即最外层括号外、最右边的[乘],以此类推……

表达式处理:除了基本的处理:去除空白符、去除前导零外,有一个特殊的处理——将最外层括号替换为方括号[],方便解析

表达式存储:分两层逻辑结构存储——基本项(Term)和由若干个基本项组成的表达式(Expr);Term存储系数和指数,Expr存储Term的数组Arraylist<Term>

表达式输出:在Term和Expr中都实现toString()方法,Expr.toString()需要下降到Term.toString()输出

UML类图

img

代码规模

Total LinesSource Code LinesSource Code Lines [%]Comment LinesComment Lines [%]Blank LinesBlank Lines [%]
Lexer.java1188572%1513%1815%
Main.java121192%00%18%
Operator.java1059086%66%99%
Parser.java13311687%108%75%
Term.java574782%12%916%
Total:42534982%328%4410%

复杂度分析

方法复杂度
MethodCogCev(G)iv(G)v(G)
Lexer.Lexer(String)0111
Lexer.deleteOut(String)3091216
Lexer.getString()0111
Lexer.preprocess(String)3134
Lexer.replaceAddsub(String)19168
Lexer.replaceTop(String)10166
Main.main(String[])0111
Operator.add(ArrayList, ArrayList)0111
Operator.combine(ArrayList)11577
Operator.mul(ArrayList, ArrayList)6144
Operator.parse(String)2122
Operator.pow(ArrayList, ArrayList)2233
Operator.sub(ArrayList, ArrayList)1122
Parser.Parser(String)0111
Parser.calulate()12155
Parser.lastAddsub(String)13158
Parser.lastMul(String)8126
Parser.lastPow(String)8126
Parser.toString()9356
factor.Term.Term(BigInteger, int, BigInteger)0111
factor.Term.addCoef(BigInteger)0111
factor.Term.getCoef()0111
factor.Term.getIndex()0111
factor.Term.getType()0111
factor.Term.mulCoef(BigInteger)0111
factor.Term.toString()14869
Total1484881103
Average5.691.853.123.96
类复杂度
ClassOCavgOCmaxWMC
Lexer51130
Main111
Operator3618
Parser5.17731
factor.Term2.14915
Total95
Average3.656.8019.00

第二次作业

新增了自定义函数指数函数

迭代如下:

自定义函数

主程序新增——读入:建立字符串表,如将f(y,x)=x^2+y^2存储为["f", "yx", "x^2+y^2"]

表达式解析:新增——调用:根据在最外层括号外的逗号识别对应关系,再替换,如f(f(2,2),3)先识别出f,进入括号内,分割成["f(2,2)", "3"],当然分割前最外层括号已经是方括号了,然后替换时,先替换x,再替换y和z,否则会出现错误

指数函数

表达式解析:新增——parseExp,即识别到e()则进入解析

表达式处理:新增——将"exp"替换成"e",防止自定义函数调用时将exp的x替换掉

表达式存储:新增——Term新增名为expExpr的Expr对象,存储exp()括号里的表达式

表达式输出:新增——Term新增expExprToString()来打印exp()括号里的表达式

共同影响:

表达式解析:改变优先级序列:[fgh、exp]>乘方>……

UML类图

img

代码规模

Total LinesSource Code LinesSource Code Lines [%]Comment LinesComment Lines [%]Blank LinesBlank Lines [%]
Add.java262285%28%28%
Expr.java1028482%55%1313%
Func.java312684%26%310%
Lexer.java13110177%118%1915%
Main.java242188%14%28%
Mul.java716287%23%710%
Parser.java14912685%117%128%
Pow.java292276%13%621%
Sub.java322681%26%413%
Term.java26922082%114%3814%
Total:86471082%486%10612%

复杂度分析

方法复杂度
MethodCogCev(G)iv(G)v(G)
Main.main(String[])1122
factor.Expr.Expr()0111
factor.Expr.Expr(Expr)1122
factor.Expr.Expr(Term)0111
factor.Expr.addTerm(Term)0111
factor.Expr.deleteZeroTerm()0111
factor.Expr.getTerms()0111
factor.Expr.isEqual(Expr)18949
factor.Expr.sortPositive()4334
factor.Expr.toString()8467
factor.Term.Term(BigInteger, int, BigInteger)0111
factor.Term.Term(Term)2133
factor.Term.addCoef(BigInteger)0111
factor.Term.addCos(Expr)0111
factor.Term.addIndex(BigInteger)0111
factor.Term.addSin(Expr)0111
factor.Term.addexpExpr(Expr)0111
factor.Term.divCoef(BigInteger)0111
factor.Term.expExprToString()18678
factor.Term.getCoef()0111
factor.Term.getCosList()0111
factor.Term.getExpExpr()0111
factor.Term.getIndex()0111
factor.Term.getSinList()0111
factor.Term.isEqual(Term)5616
factor.Term.isEqualCosList(Term)199510
factor.Term.isEqualSinList(Term)199510
factor.Term.isMergableTerm(Term)4425
factor.Term.isNum()1144
factor.Term.isZeroTerm()5525
factor.Term.mulCoef(BigInteger)0111
factor.Term.powString()10758
factor.Term.toString()1811115
operator.Add.add(Expr, Expr)10657
operator.Func.change(String, String, String)4155
operator.Mul.mul(Expr, Expr)5245
operator.Mul.mul(Term, Term)1991012
operator.Pow.pow(Expr, Expr)3324
operator.Sub.sub(Expr, Expr)11668
parse.Lexer.deleteOut(String)3091216
parse.Lexer.parseFunc(String)3133
parse.Lexer.preprocess(String)3134
parse.Lexer.replaceAddsub(String)19168
parse.Lexer.replaceTop(String)11267
parse.Parser.finalParse(String)7658
parse.Parser.lastAddsub(String)14169
parse.Parser.lastMul(String)8126
parse.Parser.lastPow(String)8126
parse.Parser.parseCos(String)0111
parse.Parser.parseExp(String)0111
parse.Parser.parseExpr(String)18555
parse.Parser.parseFunc(String)0111
parse.Parser.parseSin(String)0111
Total306144166233
Average5.772.723.134.40
类复杂度
ClassOCavgOCmaxWMC
Main222
factor.Expr2.78925
factor.Term3.351177
operator.Add777
operator.Func555
operator.Mul7.51115
operator.Pow444
operator.Sub888
parse.Lexer6.41132
parse.Parser3.78734
Total209
Average3.947.5020.90

第三次作业

新增了允许函数嵌套求导因子

迭代如下:(函数嵌套已经在第二次作业实现,只需对求导因子迭代)

表达式解析:改变优先级序列:[dx、fhg、exp]>乘方……;新增parseDeriv,即识别到d()则进入,返回表达式求导后的结果,因此实现了Expr和Term的deriv方法,由于Term的形式固定,则其求导后的格式固定,很好实现

表达式处理:新增——将"dx"替换成"d"

UML类图

img

代码规模

Total LinesSource Code LinesSource Code Lines [%]Comment LinesComment Lines [%]Blank LinesBlank Lines [%]
Add.java262285%28%28%
Expr.java1189883%54%1513%
Func.java312684%26%310%
Lexer.java13310277%118%2015%
Main.java242188%14%28%
Mul.java713144%3549%57%
Parser.java15911874%3019%117%
Pow.java302377%13%620%
Sub.java322681%26%413%
Term.java33017252%12738%319%
Total:95463967%21623%9910%

复杂度分析

方法复杂度
MethodCogCev(G)iv(G)v(G)
Main.main(String[])1122
factor.Expr.Expr()0111
factor.Expr.Expr(Expr)6144
factor.Expr.Expr(Term)1122
factor.Expr.addTerm(Term)1122
factor.Expr.deleteZeroTerm()0111
factor.Expr.deriv()2223
factor.Expr.getTerms()0111
factor.Expr.isEqual(Expr)18949
factor.Expr.sortPositive()4334
factor.Expr.toString()8467
factor.Term.Term(BigInteger, int, BigInteger)0111
factor.Term.Term(Term)0111
factor.Term.addCoef(BigInteger)0111
factor.Term.addIndex(BigInteger)0111
factor.Term.addexpExpr(Expr)0111
factor.Term.calBonus(BigInteger)5145
factor.Term.deriv()0111
factor.Term.divCoef(BigInteger)0111
factor.Term.expExprToString()21778
factor.Term.getCoef()0111
factor.Term.getExpExpr()0111
factor.Term.getIndex()0111
factor.Term.isEqual(Term)3414
factor.Term.isMergableTerm(Term)2313
factor.Term.isNum()1122
factor.Term.isZeroTerm()1212
factor.Term.mostBonusFactor()8246
factor.Term.mulCoef(BigInteger)0111
factor.Term.powString()10758
factor.Term.toString()6145
operator.Add.add(Expr, Expr)10657
operator.Func.change(String, String, String)4155
operator.Mul.mul(Expr, Expr)5245
operator.Mul.mul(Term, Term)3324
operator.Pow.pow(Expr, Expr)3324
operator.Sub.sub(Expr, Expr)11668
parse.Lexer.deleteOut(String)3091216
parse.Lexer.parseFunc(String)3133
parse.Lexer.preprocess(String)3134
parse.Lexer.replaceAddsub(String)19168
parse.Lexer.replaceTop(String)11267
parse.Parser.finalParse(String)6547
parse.Parser.lastAddsub(String)14169
parse.Parser.lastMul(String)8126
parse.Parser.lastPow(String)8126
parse.Parser.parseDeriv(String)0111
parse.Parser.parseExp(String)0111
parse.Parser.parseExpr(String)18555
parse.Parser.parseFunc(String)0111
Total254115144197
Average5.082.32.883.94
类复杂度
ClassOCavgOCmaxWMC
Main222
factor.Expr3.2932
factor.Term2.55851
operator.Add777
operator.Func555
operator.Mul3.547
operator.Pow444
operator.Sub888
parse.Lexer6.41132
parse.Parser4732
Total180
Average3.66.518

基于度量来分析自己的程序结构:

缺点:三次作业代码的复杂度都明显高于别人的代码

优点:代码量少,最终作业除去注释只有639行;UML图简洁

架构设计体验:

我采用的“根据最后运算的运算符分割”的二分法,能很好应对表达式的解析问题,所以没有进行重构;如果加入三角函数,就增加基本项Term的存储形式即可,如 HashMap<Expr, BigInteger> sinList

分析自己程序的bug:

没有公测和被互测的bug

分析自己发现别人程序bug所采用的策略:

  • 采用黑盒测试策略,使用随机数据输入,与python的sympy库函数比较输出,但是并没有结合被测程序的代码设计结构来设计测试用例
  • 有效性:3次A房都能hack到别人,但由于自己写的评测机有漏洞,很多bug没有hack到,比如数据生成不完备、没有实现计算耗时的功能

分析自己进行的优化:

  • 能省略的0和1都省略了,方法是特判系数、指数是否是0或1,据此输出

  • exp部分实现提公因数时,比较不同公因数的长度影响,方法根据cxc的想法实现,枚举 i (2 <= i <= 9),若 i 整除最大公因数 gcd,则比较提取公因数 (gcd / i) 的长度影响

  • 不懂如何实现exp的“分裂”优化,如

    exp((1-2576816*x^4-25768160*x^7-96630600*x^10-161051000*x^13-100656875*x^16))^4
    

    的非常好形式是

    exp((-625*x^16-1000*x^13-600*x^10-160*x^7-16*x^4))^644204*exp(4)
    

    使我性能分得到21分

心得体会:

  • 没想到某些看似非常简单的方法的复杂度居然会非常高,比如一个删除最外层括号的方法,认知复杂度居然达到了30,但有注释,应该可以抵消此影响

未来方向:

  • 课程组提供一些优化思路的实现方法,比如exp的优化,因为优化本质也是一种面向对象的迭代
...全文
40 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

301

社区成员

发帖
与我相关
我的任务
社区描述
2023年北航面向对象设计与构造
学习 高校
社区管理员
  • YannaZhang
  • CajZella
  • C_ecelia
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧