第一单元的任务是通过对表达式结构进行建模,完成多层嵌套表达式和函数调用的括号展开与化简,在这个单元的学习中,我学习了如何通过数据层次以及行为层次进行设计,并以面向对象的方式思考问题,熟悉了正则表达式处理字符串的手段,了解了对于代码的不断更新迭代满足需求。本单元的三次作业难度层层递进,下面我将分别介绍。
1、第一次作业
通过对表达式结构进行建模,完成单变量多项式的括号展开,初步体会层次化设计的思想。
1.1数据结构
Mainclass将输入的字符串进行预处理(去掉空白符与多余的符号并将“++”和“--”化简为“+”),之后将处理过的表达式字符串传给parse中的parseExpression,先将字符串赋值给Expression类中before和after,再用正则表达式进行字符串处理进行项的切割,之后将处理过的项字符串传给parse中的parseTerm,先将字符串赋值给Term类中before和after,再用正则表达式进行字符串处理进行因子的切割,之后将处理过的因子字符串传给parse中的parseFactor,先将字符串赋值给Factor类中before和after,此时已经递归到最低层,然后调用Expression、Term、Factor类中的calculate方法通过正则表达式进行括号拆解后传给类中的after,层层递归回Expression类,最终得到的Expression类的after便是括号拆解后的表达式。

 

 


1.2代码结构分析

Expression.add(String) 0.0 1.0 1.0 1.0
Expression.addTerm(Term) 0.0 1.0 1.0 1.0
Expression.calculate() 4.0 1.0 5.0 5.0
Expression.curtailment(String) 0.0 1.0 1.0 1.0
Expression.Expression() 0.0 1.0 1.0 1.0
Expression.getAfter() 0.0 1.0 1.0 1.0
Expression.getBefore() 0.0 1.0 1.0 1.0
Expression.reverse(String) 6.0 1.0 7.0 7.0
Expression.setAfter(String) 0.0 1.0 1.0 1.0
Expression.setBefore(String) 0.0 1.0 1.0 1.0
Expression.sub(String) 0.0 1.0 1.0 1.0
Factor.calculate() 2.0 1.0 2.0 2.0
Factor.curtailment(String) 0.0 1.0 1.0 1.0
Factor.getAfter() 0.0 1.0 1.0 1.0
Factor.getBefore() 0.0 1.0 1.0 1.0
Factor.pow(String) 4.0 3.0 3.0 3.0
Factor.setAfter(String) 0.0 1.0 1.0 1.0
Factor.setBefore(String) 0.0 1.0 1.0 1.0
Mainclass.curtailment(String) 1.0 1.0 2.0 2.0
Mainclass.main(String[]) 0.0 1.0 1.0 1.0
Parser.curtailment(String) 0.0 1.0 1.0 1.0
Parser.parseExpr(String) 1.0 1.0 2.0 2.0
Parser.parseFactor(String) 0.0 1.0 1.0 1.0
Parser.parseTerm(String) 1.0 1.0 2.0 2.0
pattern.getAddexpressionfactor() 0.0 1.0 1.0 1.0
pattern.getBeginexpressionfactor() 0.0 1.0 1.0 1.0
pattern.getExpressionfactor() 0.0 1.0 1.0 1.0
pattern.getExpressionfactormul() 0.0 1.0 1.0 1.0
pattern.getExpressionmulfactor() 0.0 1.0 1.0 1.0
pattern.getMulexpressionfactor() 0.0 1.0 1.0 1.0
pattern.getMultiplyexpression() 0.0 1.0 1.0 1.0
pattern.getNoexpressionexpression() 0.0 1.0 1.0 1.0
pattern.getNoexpressionfactor() 0.0 1.0 1.0 1.0
pattern.getNoexpressionterm() 0.0 1.0 1.0 1.0
pattern.getPowerexpressionfactor() 0.0 1.0 1.0 1.0
pattern.getSubexpressionfactor() 0.0 1.0 1.0 1.0
pattern.getUltimateexpression() 0.0 1.0 1.0 1.0
pattern.getUltimatefactor() 0.0 1.0 1.0 1.0
pattern.getUltimateterm() 0.0 1.0 1.0 1.0
pattern.pattern() 0.0 1.0 1.0 1.0
Term.addFactor(Factor) 0.0 1.0 1.0 1.0
Term.calculate() 2.0 1.0 3.0 3.0
Term.curtailment(String) 0.0 1.0 1.0 1.0
Term.getAfter() 0.0 1.0 1.0 1.0
Term.getBefore() 0.0 1.0 1.0 1.0
Term.getFactors() 0.0 1.0 1.0 1.0
Term.multi(String) 48.0 1.0 19.0 19.0
Term.setAfter(String) 0.0 1.0 1.0 1.0
Term.setBefore(String) 0.0 1.0 1.0 1.0
Term.Term() 0.0 1.0 1.0 1.0
Total 69.0 52.0 86.0 86.0
Average 1.38 1.04 1.72 1.72

 

2、第二次作业
通过对表达式结构进行建模,添加了三角函数、自定义函数、求和函数,完成多项式的括号展开与函数调用、化简,进一步体会层次化设计的思想。
2.1数据结构
本次作业括号嵌套层数有限,因此我依旧采用了正则表达式进行解析,添加了Constant、Expressionfactor、Selfdefine、Summation、Trigonometric类继承在Factor类之下,Mainclass先读入自定义函数展开自定义函数表达式,并将自定义函数中的函数自变量换为a/b/c之后存储函数表达式,后将输入的字符串进行预处理(去掉空白符与多余的符号并将“++”和“--”化简为“+”并将三角函数括号转为[]),之后将处理过的表达式字符串传给parse中的parseExpression,先将字符串赋值给Expression类中before和after,再用正则表达式进行字符串处理进行项的切割,之后将处理过的项字符串传给parse中的parseTerm,先将字符串赋值给Term类中before和after,再用正则表达式进行字符串处理进行因子的切割,之后将处理过的因子字符串传给parse中的parseFactor,先将字符串赋值给Factor类中before和after,此时已经递归到最低层,然后调用Expression、Term、Factor类中的calculate方法通过正则表达式进行括号拆解后传给类中的after,层层递归回Expression类,最终得到的Expression类的after便是括号拆解后的表达式。

 

 


2.2代码结构分析

Constant.calculate() 0.0 1.0 1.0 1.0
Expression.add(String) 0.0 1.0 1.0 1.0
Expression.addTerm(Term) 0.0 1.0 1.0 1.0
Expression.calculate() 8.0 1.0 8.0 8.0
Expression.curtailment(String) 0.0 1.0 1.0 1.0
Expression.Expression() 0.0 1.0 1.0 1.0
Expression.getAfter() 0.0 1.0 1.0 1.0
Expression.getBefore() 0.0 1.0 1.0 1.0
Expression.reverse(String) 6.0 1.0 7.0 7.0
Expression.setAfter(String) 0.0 1.0 1.0 1.0
Expression.setBefore(String) 0.0 1.0 1.0 1.0
Expression.sub(String) 0.0 1.0 1.0 1.0
Expressionfactor.addExpression(Expression) 0.0 1.0 1.0 1.0
Expressionfactor.calculate() 2.0 1.0 3.0 3.0
Expressionfactor.Expressionfactor() 0.0 1.0 1.0 1.0
Expressionfactor.pow(String) 4.0 3.0 3.0 3.0
Factor.curtailment(String) 0.0 1.0 1.0 1.0
Factor.getAfter() 0.0 1.0 1.0 1.0
Factor.getBefore() 0.0 1.0 1.0 1.0
Factor.setAfter(String) 0.0 1.0 1.0 1.0
Factor.setBefore(String) 0.0 1.0 1.0 1.0
Mainclass.curtailment(String) 5.0 1.0 5.0 5.0
Mainclass.getStrings() 0.0 1.0 1.0 1.0
Mainclass.main(String[]) 4.0 1.0 4.0 4.0
Mypattern.getAddexpressionfactor() 0.0 1.0 1.0 1.0
Mypattern.getArgument() 0.0 1.0 1.0 1.0
Mypattern.getBeginexpressionfactor() 0.0 1.0 1.0 1.0
Mypattern.getBesummed() 0.0 1.0 1.0 1.0
Mypattern.getExponent() 0.0 1.0 1.0 1.0
Mypattern.getExpressionfactor() 0.0 1.0 1.0 1.0
Mypattern.getExpressionfactormul() 0.0 1.0 1.0 1.0
Mypattern.getExpressionmulfactor() 0.0 1.0 1.0 1.0
Mypattern.getFunctionalexpression() 0.0 1.0 1.0 1.0
Mypattern.getHaveexponenttrifunction() 0.0 1.0 1.0 1.0
Mypattern.getMulexpressionfactor() 0.0 1.0 1.0 1.0
Mypattern.getMultiplyexpression() 0.0 1.0 1.0 1.0
Mypattern.getNewaddexpresionfactor() 0.0 1.0 1.0 1.0
Mypattern.getNewbgnexpresionfactor() 0.0 1.0 1.0 1.0
Mypattern.getNewbracketexpressionfactor() 0.0 1.0 1.0 1.0
Mypattern.getNewexpressionfactor() 0.0 1.0 1.0 1.0
Mypattern.getNewnoexponentexpfac() 0.0 1.0 1.0 1.0
Mypattern.getNewnoexpressionexpression() 0.0 1.0 1.0 1.0
Mypattern.getNewnoexpressionfactor() 0.0 1.0 1.0 1.0
Mypattern.getNewnoexpressionterm() 0.0 1.0 1.0 1.0
Mypattern.getNewpowerexpressionfactor() 0.0 1.0 1.0 1.0
Mypattern.getNewsubexpresionfactor() 0.0 1.0 1.0 1.0
Mypattern.getNoexpressionexpression() 0.0 1.0 1.0 1.0
Mypattern.getNoexpressionfactor() 0.0 1.0 1.0 1.0
Mypattern.getNoexpressionterm() 0.0 1.0 1.0 1.0
Mypattern.getNoselfsumexpression() 0.0 1.0 1.0 1.0
Mypattern.getNoselfsumexpressionfactor() 0.0 1.0 1.0 1.0
Mypattern.getNoselfsumterm() 0.0 1.0 1.0 1.0
Mypattern.getOnlytrigonometricfunction() 0.0 1.0 1.0 1.0
Mypattern.getPowerexpressionfactor() 0.0 1.0 1.0 1.0
Mypattern.getPowerfunction() 0.0 1.0 1.0 1.0
Mypattern.getSelffunctioncall() 0.0 1.0 1.0 1.0
Mypattern.getSelffunctiondefine() 0.0 1.0 1.0 1.0
Mypattern.getSelffunctionname() 0.0 1.0 1.0 1.0
Mypattern.getSinfunctionname() 0.0 1.0 1.0 1.0
Mypattern.getSubexpressionfactor() 0.0 1.0 1.0 1.0
Mypattern.getSubtituteargument() 0.0 1.0 1.0 1.0
Mypattern.getSummationexpressionfactor() 0.0 1.0 1.0 1.0
Mypattern.getSummationfunction() 0.0 1.0 1.0 1.0
Mypattern.getTrigonometricfunction() 0.0 1.0 1.0 1.0
Mypattern.getUltimateexpression() 0.0 1.0 1.0 1.0
Mypattern.getUltimatefactor() 0.0 1.0 1.0 1.0
Mypattern.getUltimatenoselfsumexpression() 0.0 1.0 1.0 1.0
Mypattern.getUltimateterm() 0.0 1.0 1.0 1.0
Parser.curtailment(String) 0.0 1.0 1.0 1.0
Parser.parseExpr(String) 1.0 1.0 2.0 2.0
Parser.parseFactor(String) 11.0 5.0 8.0 8.0
Parser.parseTerm(String) 1.0 1.0 2.0 2.0
Selfdefine.addExpression(Expression) 0.0 1.0 1.0 1.0
Selfdefine.calculate() 1.0 1.0 2.0 2.0
Selfdefine.Selfdefine() 0.0 1.0 1.0 1.0
Selfdefine.substitute(String) 12.0 4.0 7.0 7.0
Summation.addExpression(Expression) 0.0 1.0 1.0 1.0
Summation.calculate() 1.0 1.0 2.0 2.0
Summation.substitute(String) 5.0 1.0 4.0 4.0
Summation.Summation() 0.0 1.0 1.0 1.0
Term.addFactor(Factor) 0.0 1.0 1.0 1.0
Term.calculate() 7.0 3.0 7.0 7.0
Term.curtailment(String) 0.0 1.0 1.0 1.0
Term.getAfter() 0.0 1.0 1.0 1.0
Term.getBefore() 0.0 1.0 1.0 1.0
Term.getFactors() 0.0 1.0 1.0 1.0
Term.multi(String) 48.0 1.0 19.0 19.0
Term.setAfter(String) 0.0 1.0 1.0 1.0
Term.setBefore(String) 0.0 1.0 1.0 1.0
Term.Term() 0.0 1.0 1.0 1.0
Trigonometric.calculate() 2.0 1.0 2.0 2.0
Trigonometric.pow(String) 4.0 3.0 3.0 3.0
Total 122.0 105.0 163.0 163.0
Average 1.326086956521739 1.141304347826087 1.7717391304347827 1.7717391304347827

2.3bug修复
表达式解析之后,自定义函数外的括号没有被解析,自定义函数解析时可能出现多层括号嵌套的情况,导致通过正则表达式无法解析到无非必要括号的表达式,只有重构才能解决这个问题。

 

3、第三次作业
通过对表达式结构进行建模,完成多层嵌套表达式和函数调用的括号展开与化简,进一步体会层次化设计的思想,本次作业未添加其他函数,但是提出了多层括号嵌套的需求。
3.1数据结构
本次作业在第二次作业的基础上又增加了新的需求,出现了多层括号嵌套因此无法再使用正则表达式进行解析,在这次作业中我进行了代码重构。首先读入自定义函数存储并进行解析,之后读入表达式,Mainclass将输入的字符串进行预处理(去掉空格),调用Lexer解析工具类,之后传入lexer工具和自定义函数容器进入parse类的parseExpression方法,运用lexer工具拆解表达式成为若干项进入parseTerm方法,运用lexer工具拆解项成为若干因子进入parseNested方法,在parseNested方法中再次用lexer工具按照因子的不同分类进入parseExpression方法、parseCosfactor方法、parseSinfactor方法、parseSummation方法、parseSelfdefine方法、构建常量因子 Constfactor、构建变量因子 Indvarfactor,层层递归到数据层次的最底层,之后调用各类中的debrackets方法得到最终被解析的表达式。

 

 


3.2代码结构分析

Constfactor.Constfactor(String) 0.0 1.0 1.0 1.0
Constfactor.debrackets() 0.0 1.0 1.0 1.0
Constfactor.equal(Object) 3.0 2.0 2.0 3.0
Constfactor.getNum() 0.0 1.0 1.0 1.0
Constfactor.toString() 0.0 1.0 1.0 1.0
Cosfactor.Cosfactor(Nestedfactor) 0.0 1.0 1.0 1.0
Cosfactor.debrackets() 1.0 2.0 1.0 2.0
Cosfactor.equal(Object) 3.0 2.0 2.0 3.0
Cosfactor.toString() 0.0 1.0 1.0 1.0
Expression.addNestedfactor(Nestedfactor) 0.0 1.0 1.0 1.0
Expression.debrackets() 4.0 1.0 3.0 3.0
Expression.equal(Object) 0.0 1.0 1.0 1.0
Expression.Expression() 0.0 1.0 1.0 1.0
Expression.getNesteds() 0.0 1.0 1.0 1.0
Expression.setNesteds(ArrayList) 0.0 1.0 1.0 1.0
Expression.toString() 8.0 2.0 4.0 4.0
Factory.manufacture(Lexer) 2.0 1.0 3.0 3.0
Indvarfactor.debrackets() 0.0 1.0 1.0 1.0
Indvarfactor.equal(Object) 3.0 2.0 2.0 3.0
Indvarfactor.Indvarfactor(String) 0.0 1.0 1.0 1.0
Indvarfactor.toString() 0.0 1.0 1.0 1.0
Lexer.getelse() 0.0 1.0 1.0 1.0
Lexer.getLetter() 2.0 1.0 3.0 3.0
Lexer.getNum() 2.0 1.0 3.0 3.0
Lexer.getToken() 0.0 1.0 1.0 1.0
Lexer.Lexer(String) 0.0 1.0 1.0 1.0
Lexer.next() 6.0 2.0 4.0 4.0
Lexer.peek() 2.0 2.0 2.0 2.0
Mainclass.curtailment(String) 0.0 1.0 1.0 1.0
Mainclass.main(String[]) 3.0 1.0 3.0 3.0
Mainclass.removeconstone(Nestedfactor) 16.0 1.0 7.0 7.0
Mypattern.getAddminusPattern() 0.0 1.0 1.0 1.0
Mypattern.getletterPattern() 0.0 1.0 1.0 1.0
Mypattern.getNumPattern() 0.0 1.0 1.0 1.0
Parse.getParameter() 1.0 1.0 2.0 2.0
Parse.getTermcoef() 1.0 1.0 2.0 2.0
Parse.isSelfdefine(String) 3.0 3.0 2.0 3.0
Parse.Parse(Lexer) 0.0 1.0 1.0 1.0
Parse.Parse(Lexer, ArrayList) 0.0 1.0 1.0 1.0
Parse.parseCosfactor() 0.0 1.0 1.0 1.0
Parse.parseExponent(Nestedfactor) 5.0 2.0 4.0 4.0
Parse.parseExpression() 1.0 1.0 2.0 2.0
Parse.parseNested() 25.0 12.0 13.0 13.0
Parse.parseSelfdefine(String) 4.0 1.0 3.0 4.0
Parse.parseSinfactor() 0.0 1.0 1.0 1.0
Parse.parseSummation() 0.0 1.0 1.0 1.0
Parse.parseTerm() 1.0 1.0 2.0 2.0
Powerfactor.debrackets() 6.0 4.0 5.0 5.0
Powerfactor.equal(Object) 3.0 2.0 3.0 4.0
Powerfactor.Powerfactor(Nestedfactor, BigInteger) 0.0 1.0 1.0 1.0
Powerfactor.toString() 2.0 2.0 2.0 2.0
Selfdefine.getExpression() 0.0 1.0 1.0 1.0
Selfdefine.getFuncionname() 0.0 1.0 1.0 1.0
Selfdefine.getVarities() 0.0 1.0 1.0 1.0
Selfdefine.Selfdefine() 0.0 1.0 1.0 1.0
Selfdefine.Selfdefine(String, ArrayList, String) 0.0 1.0 1.0 1.0
Selfdefine.substitute(ArrayList) 2.0 1.0 3.0 3.0
Selfdefine.toString() 1.0 1.0 2.0 2.0
Sinfactor.debrackets() 1.0 2.0 1.0 2.0
Sinfactor.equal(Object) 3.0 2.0 2.0 3.0
Sinfactor.Sinfactor(Nestedfactor) 0.0 1.0 1.0 1.0
Sinfactor.toString() 0.0 1.0 1.0 1.0
Summation.extend() 8.0 1.0 5.0 5.0
Summation.Summation(String, String, String, String) 0.0 1.0 1.0 1.0
Term.addAllNestedfactor(ArrayList) 0.0 1.0 1.0 1.0
Term.addNestedfactor(Nestedfactor) 0.0 1.0 1.0 1.0
Term.debrackets() 6.0 5.0 5.0 5.0
Term.equal(Object) 0.0 1.0 1.0 1.0
Term.expmultiplyNest(Expression, Nestedfactor) 1.0 1.0 2.0 2.0
Term.getNesteds() 0.0 1.0 1.0 1.0
Term.getTermcoef() 2.0 2.0 2.0 2.0
Term.hasexpression(ArrayList) 3.0 3.0 1.0 3.0
Term.multiply(ArrayList) 7.0 2.0 4.0 4.0
Term.multiplytwo(Expression, Expression) 3.0 1.0 3.0 3.0
Term.setNesteds(ArrayList) 0.0 1.0 1.0 1.0
Term.Term() 0.0 1.0 1.0 1.0
Term.toString() 9.0 1.0 6.0 6.0
Total 153.0 113.0 156.0 167.0
Average 1.9870129870129871 1.4675324675324675 2.0259740259740258 2.168831168831169

 

3.3bug修复
表达式解析没有问题,问题出现在解析后表达式缩减的问题,replaceAll("([*]{1}[1]{1})*","")在样例“x**11*cos(x)”中缩减错误,解决方法:“replaceAll("[*]{2}","^")”先将“**”转换成“^”之后再转换回来,对于缩减后表达式过长的问题,解决方法:在Term类中debrackets方法将含有常量因子“0”的项置为零项。

4、bug分析
个人认为搭建一个自动测试是十分重要的,软件的效率远远高于我自己debug的效率,因此在第二单元中我希望自己能搭建出来一个自己的自动测试程序。
5、hack策略
在本单元的互测阶段中,我发现同学的bug点主要集中于边界测试点例如表达式缩减后为0,常量因子数据大小在long的范围之外。
6、架构设计体验
在第一次作业中,我将绝大部分时间都放在了架构设计上,其中有多次返工,导致时间很紧,现在能从中总结出些许经验,打代码之前要有严谨的架构设计,可以大概将思路画在草稿上简单的代入一个样例大概走一遍代码。在第二次作业中由于有了三角函数,自定义函数,求和函数等的简单括号嵌套,正则表达式程序还是依旧能够使用,但是可以看出第二次作业的程序几乎无法在进行需求添加,一旦第三次作业有更多需求,代码只能重构,果不其然,在第三次中我只能重构代码,采取另一种解析方式,因此个人认为初期的框架设计十分重要,程序一定要留有需求扩展空间。
7、心得体会
OO第一单元强调锻炼数据与层次方面设计以及递归方法,在框架设计的时候如果要采用递归方法是真的复杂,对于我来说大量采用递归方法还是第一次,这也导致我第一次作业寸步难行,不断返工,希望在第二单元中能学习到更多的JAVA知识。