301
社区成员
发帖
与我相关
我的任务
分享第一单元的三次作业主体为化简多项式,包括最初的单纯化简括号,到第二次加入的exp与自定义函数与最终的加入导数,最初代码的复杂程度让包括我在内的部分初学者感到了较大的压力,但最终我还是克服了一系列挑战,完成了每一次的初步提交与后续的bug修复。
第一次作业要求对于输入的多项式进行至少化简掉括号的初步化简,其核心思路为递归下降,即将表达式分为多项式-项-因子三类,因子之间用乘法来链接形成项,项之间用加法链接形成多项式,在进行这样的初步加工后再进行对应的合并运算。这其中最大的挑战便是因子中会包含带有括号的表达式因子,这时一方面要通过递归对表达式因子进行进一步的化简,从而实现最终架构的统一,另一方面通过对于多项式、项、因子三类共同接入一个Factor的接口,实现三类结构上的统一并处理因子。

很遗憾,由于我个人的能力问题,三次作业都没能成功入围互测环节,只能在强测开放后完成bug修复。
第二次作业加入了Exp与自定义函数,其中前者的处理相等较为简单,在Parse类调用lexer读取时只需连续调用四次next()方法(目的是使pos指向Exp内部的表达式因子),然后调用处理表达式的ParseExpr方法得到其内部的表达式即可。下图为next()方法与处理Exp部分的代码。
public void next() { //返回下一个读入的数字、符号或函数名称
if (pos == input.length()) { //读到末尾则停止
return;
}
char c = input.charAt(pos);
if (Character.isDigit(c)) { //读到数字
curToken = getNumber();
} else /*if ( /TODO/ )*/ { //读到"+","-","^"等符号以及f,g,h等函数名
pos += 1;
curToken = String.valueOf(c);
}
}
for (int i = 0; i < 4; i++) {
lexer.next();
} //注意:这里故意让next执行4+n次,从而使peek指向"(",从而在后续调用parseExpr函数时遇到")"会自动结束
Expr expr = parseExpr(); //调用处理Expr的方法
Final final1 = Cal.finalexpr(expr);
data.setExp(final1); //将得到Expr转化成Final类型再存入data的Expr中
自定义函数的处理相等较为困难,一般有两种处理方法,一种是在读取完函数后立刻对于解析式中的函数进行替换(如读完函数f(x) = x + 1)后将所有的f(a)替换为a + 1(a为任意的多项式因子),另一种是直接在Parse解析的方法中加入f,g,h三种函数的处理方法,考虑到实操性,这里我采用的是后者,即在ParseFactor(处理因子的函数)中加入了读到自定义函数(即f,g,h)时的操作,然后结合之前读到函数的表达式进行替换并得到一个新的表达式因子(这是是因为函数一般生成的都是表达式因子,故而我直接选择了返回表达式类型,但这样的一大弊端就是后续调试代码时由于层次的过度累加而导致的一系列不便,这是我处理细节上的一个不当之处)。

第三次作业的要求是新增求导功能,由于在第二次实验中已经给出了可以实现求一次导的代码架构,这次迭代的要求显得相对轻松,只需要像实验课中给出的代码中一样,在多项式内部实现加法法则,在项内部实现乘法法则,而在表达式因子内部实现链式法则即可,相对来说没有特别困难的地方。
由于新增求导功能只需要在原来的项内部新增方法,并没有新增新的类的需要,故而本次作业的代码架构与第二次作业类似
最终作业复杂度
| Cal.big(int) | 0.0 | 1.0 | 1.0 | 1.0 |
|---|---|---|---|---|
| Cal.dataadd(Data, Data) | 7.0 | 2.0 | 5.0 | 6.0 |
| Cal.datamult(Data, Data) | 8.0 | 1.0 | 5.0 | 5.0 |
| Cal.finaladddata(Final, Data) | 10.0 | 4.0 | 5.0 | 5.0 |
| Cal.finaladdfinal(Final, Final) | 1.0 | 1.0 | 2.0 | 2.0 |
| Cal.finalexpr(Factor) | 3.0 | 1.0 | 3.0 | 3.0 |
| Cal.finalfactor(Factor) | 2.0 | 3.0 | 3.0 | 3.0 |
| Cal.finalmult(Final, Final) | 6.0 | 4.0 | 3.0 | 4.0 |
| Data.changefront() | 0.0 | 1.0 | 1.0 | 1.0 |
| Data.changesymbol() | 2.0 | 1.0 | 1.0 | 2.0 |
| Data.clone() | 2.0 | 1.0 | 3.0 | 3.0 |
| Data.createthisfront() | 0.0 | 1.0 | 1.0 | 1.0 |
| Data.createthisxnum() | 0.0 | 1.0 | 1.0 | 1.0 |
| Data.createthisynum() | 0.0 | 1.0 | 1.0 | 1.0 |
| Data.createthisznum() | 0.0 | 1.0 | 1.0 | 1.0 |
| Data.Data(BigInteger, BigInteger, BigInteger, BigInteger, Final) | 0.0 | 1.0 | 1.0 | 1.0 |
| Data.datasame(Data, Data) | 10.0 | 4.0 | 5.0 | 6.0 |
| Data.derive() | 4.0 | 2.0 | 4.0 | 5.0 |
| Data.getExp() | 0.0 | 1.0 | 1.0 | 1.0 |
| Data.getFactors() | 0.0 | 1.0 | 1.0 | 1.0 |
| Data.getFront() | 0.0 | 1.0 | 1.0 | 1.0 |
| Data.getTerms() | 0.0 | 1.0 | 1.0 | 1.0 |
| Data.getXnum() | 0.0 | 1.0 | 1.0 | 1.0 |
| Data.getYnum() | 0.0 | 1.0 | 1.0 | 1.0 |
| Data.getZnum() | 0.0 | 1.0 | 1.0 | 1.0 |
| Data.returnfactor() | 8.0 | 1.0 | 8.0 | 8.0 |
| Data.setExp(Final) | 1.0 | 1.0 | 1.0 | 2.0 |
| Data.setFront(BigInteger) | 0.0 | 1.0 | 1.0 | 1.0 |
| Data.setXnum(BigInteger) | 0.0 | 1.0 | 1.0 | 1.0 |
| Data.setZnum(BigInteger) | 0.0 | 1.0 | 1.0 | 1.0 |
| Definedfunc.addFuncs(Func) | 0.0 | 1.0 | 1.0 | 1.0 |
| Definedfunc.Definedfunc() | 0.0 | 1.0 | 1.0 | 1.0 |
| Definedfunc.getFuncs() | 0.0 | 1.0 | 1.0 | 1.0 |
| Definedfunc.isalp(String, Data) | 8.0 | 1.0 | 5.0 | 8.0 |
| Definedfunc.multfactor(Factor) | 5.0 | 1.0 | 3.0 | 3.0 |
| Definedfunc.returnData(Data, ArrayList, Func) | 7.0 | 1.0 | 6.0 | 6.0 |
| Definedfunc.returndata0(BigInteger, Factor) | 1.0 | 1.0 | 2.0 | 2.0 |
| Definedfunc.returnexpr(Factor, ArrayList, Func) | 4.0 | 2.0 | 3.0 | 4.0 |
| Definedfunc.returnfactor(Factor, ArrayList, Func) | 2.0 | 1.0 | 2.0 | 2.0 |
| Definedfunc.returnterm(Term, ArrayList, Func) | 4.0 | 2.0 | 3.0 | 4.0 |
| Expr.addexpr(Expr, Data) | 5.0 | 1.0 | 6.0 | 6.0 |
| Expr.addTerm(Term) | 0.0 | 1.0 | 1.0 | 1.0 |
| Expr.changefront() | 0.0 | 1.0 | 1.0 | 1.0 |
| Expr.changesymbol() | 1.0 | 1.0 | 2.0 | 2.0 |
| Expr.clone() | 1.0 | 1.0 | 2.0 | 2.0 |
| Expr.derive() | 1.0 | 1.0 | 2.0 | 2.0 |
| Expr.Expr() | 0.0 | 1.0 | 1.0 | 1.0 |
| Expr.getFactors() | 0.0 | 1.0 | 1.0 | 1.0 |
| Expr.getFront() | 0.0 | 1.0 | 1.0 | 1.0 |
| Expr.getTerms() | 0.0 | 1.0 | 1.0 | 1.0 |
| Expr.getXnum() | 0.0 | 1.0 | 1.0 | 1.0 |
| Expr.isSymbol() | 0.0 | 1.0 | 1.0 | 1.0 |
| Expr.mergeExpr(Expr, Expr) | 2.0 | 3.0 | 1.0 | 3.0 |
| Expr.returnfactor() | 1.0 | 1.0 | 2.0 | 2.0 |
| Expr.setExp(Final) | 1.0 | 1.0 | 2.0 | 2.0 |
| Expr.setFront(BigInteger) | 1.0 | 1.0 | 2.0 | 2.0 |
| Expr.setXnum(BigInteger) | 0.0 | 1.0 | 1.0 | 1.0 |
| Expr.setYnum(BigInteger) | 0.0 | 1.0 | 1.0 | 1.0 |
| Expr.setZnum(BigInteger) | 0.0 | 1.0 | 1.0 | 1.0 |
| Final.addexpr(Expr) | 1.0 | 1.0 | 2.0 | 2.0 |
| Final.clone() | 1.0 | 1.0 | 2.0 | 2.0 |
| Final.clone(Final) | 1.0 | 1.0 | 2.0 | 2.0 |
| Final.empty() | 3.0 | 3.0 | 1.0 | 3.0 |
| Final.Final() | 0.0 | 1.0 | 1.0 | 1.0 |
| Final.finalclone(Final) | 1.0 | 1.0 | 2.0 | 2.0 |
| Final.finaldata(Data) | 0.0 | 1.0 | 1.0 | 1.0 |
| Final.finalsame(Final, Final) | 12.0 | 7.0 | 6.0 | 9.0 |
| Final.getData() | 0.0 | 1.0 | 1.0 | 1.0 |
| Final.printdata(Data) | 9.0 | 1.0 | 7.0 | 7.0 |
| Final.printfinal() | 9.0 | 1.0 | 4.0 | 8.0 |
| Final.removedata(Data) | 1.0 | 1.0 | 2.0 | 2.0 |
| Final.turnExpr() | 1.0 | 1.0 | 2.0 | 2.0 |
| Final.turnTerm() | 1.0 | 1.0 | 2.0 | 2.0 |
| Func.addParas(String) | 0.0 | 1.0 | 1.0 | 1.0 |
| Func.Func(String) | 0.0 | 1.0 | 1.0 | 1.0 |
| Func.getExpr() | 0.0 | 1.0 | 1.0 | 1.0 |
| Func.getName() | 0.0 | 1.0 | 1.0 | 1.0 |
| Func.getParas() | 0.0 | 1.0 | 1.0 | 1.0 |
| Func.setExpr(Factor) | 0.0 | 1.0 | 1.0 | 1.0 |
| Lexer.getNumber() | 2.0 | 1.0 | 3.0 | 3.0 |
| Lexer.Lexer(String) | 0.0 | 1.0 | 1.0 | 1.0 |
| Lexer.next() | 3.0 | 2.0 | 2.0 | 3.0 |
| Lexer.peek() | 0.0 | 1.0 | 1.0 | 1.0 |
| Lexer.setPos(int) | 0.0 | 1.0 | 1.0 | 1.0 |
| Main.main(String[]) | 3.0 | 1.0 | 3.0 | 3.0 |
| Main.pretreat(String) | 1.0 | 1.0 | 2.0 | 2.0 |
| Parser.delwithderive() | 1.0 | 1.0 | 2.0 | 2.0 |
| Parser.delwithexpr() | 0.0 | 1.0 | 1.0 | 1.0 |
| Parser.delwithsymbol() | 1.0 | 2.0 | 2.0 | 2.0 |
| Parser.factorg(char) | 3.0 | 1.0 | 2.0 | 6.0 |
| Parser.findfuncname(ArrayList, String) | 4.0 | 4.0 | 2.0 | 4.0 |
| Parser.methodg(char) | 1.0 | 1.0 | 2.0 | 2.0 |
| Parser.parseExpr() | 7.0 | 1.0 | 6.0 | 6.0 |
| Parser.parseFactor() | 10.0 | 3.0 | 6.0 | 6.0 |
| Parser.Parser(Lexer) | 0.0 | 1.0 | 1.0 | 1.0 |
| Parser.parseTerm() | 23.0 | 1.0 | 9.0 | 9.0 |
| Parser.renewlexer(Lexer) | 0.0 | 1.0 | 1.0 | 1.0 |
| Term.addFactor(Factor) | 0.0 | 1.0 | 1.0 | 1.0 |
| Term.changefront() | 0.0 | 1.0 | 1.0 | 1.0 |
| Term.changesymbol() | 0.0 | 1.0 | 1.0 | 1.0 |
| Term.clone() | 1.0 | 1.0 | 2.0 | 2.0 |
| Term.derive() | 8.0 | 3.0 | 4.0 | 5.0 |
| Term.getFactors() | 0.0 | 1.0 | 1.0 | 1.0 |
| Term.getFront() | 0.0 | 1.0 | 1.0 | 1.0 |
| Term.getTerms() | 0.0 | 1.0 | 1.0 | 1.0 |
| Term.getXnum() | 0.0 | 1.0 | 1.0 | 1.0 |
| Term.isSymbol() | 0.0 | 1.0 | 1.0 | 1.0 |
| Term.mergeterm(Term, Term) | 3.0 | 3.0 | 4.0 | 4.0 |
| Term.returnfactor() | 1.0 | 1.0 | 2.0 | 2.0 |
| Term.setExp(Final) | 0.0 | 1.0 | 1.0 | 1.0 |
| Term.setFront(BigInteger) | 1.0 | 1.0 | 2.0 | 2.0 |
| Term.setXnum(BigInteger) | 0.0 | 1.0 | 1.0 | 1.0 |
| Term.setYnum(BigInteger) | 0.0 | 1.0 | 1.0 | 1.0 |
| Term.setZnum(BigInteger) | 0.0 | 1.0 | 1.0 | 1.0 |
| Term.Term() | 0.0 | 1.0 | 1.0 | 1.0 |
| Total | 228.0 | 158.0 | 245.0 | 277.0 |
| Average | 1.9 | 1.3166666666666667 | 2.0416666666666665 | 2.308333333333333 |
本单元的作业主要让我学会了递归下降的处理方式,同时让我学会了层次化处理代码。我个人建议以后课程能够在中测的时候提供少量的强测样例,以便同学们能够进一步判断自己代码内部的架构,从而获得更多参加强侧的机会。