301
社区成员
发帖
与我相关
我的任务
分享
Mainclass:函数主体,读取输入,打印输出,调用其他类的顶层类
Pretreat:预处理类,将字符串进行去除前导0,去除空格,去除多余符号等预处理
Lexer:词法分析器,将字符串解析为词语集合,方便后续文件处理
Parser:语法分析器,将词语集合解析为表达式,并且递归解析项和因子
Function:自定义函数类,获取自定义函数并分析,同时提供自定义函数的代换
Factor:因子接口,用于规范因子的行为
Term:项类,在Parser中被解析
Expr:表达式类,在Parser中被解析
Number:数字类,在Parser中被解析
Power:幂函数类,在Parser中被解析
Mono:单项式类,程序处理的基本单元,包含的三个属性分别描述系数,指数,自然底数的指数,处理底层基本项的运算
Poly:多项式类,程序数据传递的主要类型,由Mono列表构成,负责处理各种顶层运算

方法复杂度分析:由于方法较多不便列出,这里只列出复杂度较高的方法并分析原因。
Poly.polyEqual(Poly, Poly):判断多项式是否相等,需要递归调用单项式相等算法,因此复杂度高
Poly.isBaseFactor(Poly):判断是否是基本项,复杂度高的主要原因是分支情况较多,使用了大量的if语句进行判断
Mono.toStringExpElse()/Mono.toStringExp1()/Mono.toStringExp0():
输出逻辑,复杂度高的原因同样是分支较多,复杂度高
由此可见,复杂度高的方法主要有两类,一类是递归调用次数较多的方法,这类方法会递归调用大量函数从而导致复杂度高;另一类是偏面向过程的方法,这类方法会产生大量分支,因此会带来高复杂度。

类复杂度分析:根据如图的复杂度分析,可知程序主要复杂度集中在Parser类,Poly类和Mono类中。出现这样的原因在于表达式解析的过程中会出现多层parser方法迭代调用的情况;而Poly类和Mono类则是本程序的主要数据结构,各种运算、化简、输出都在这两个类中实现,因此复杂度较高
hw1:第一次作业要求我们实现一个支持四则运算和单层括号的表达式解析,这次作业我主要收获是学会了通过递归下降的方式以及基于词法分析的方式进行的表达式解析。从输入处理流程看,我通过预处理,词法分析,语法分析,输出四部分进行处理;从数据格式看,我通过单项式mono作为基本项,多项式poly包含单项式列表来组织数据传递。
//main函数中的主要处理流程
input = preTreat(input);
Poly poly = parser(input);
poly.printPoly;
//数据的架构
public class Mono {
private BigInteger coe;
private int exp;
}
public class Poly {
private ArrayList<Mono> monos;
}
hw2:第二次作业在第一次作业的基础上,要求我们支持嵌套括号,指数函数和自定义函数。针对三个迭代任务,首先基于递归下降的表达式分析原生支持嵌套括号的解析;对于指数函数,我通过在mono类中新增expPoly属性来支持指数函数,通过该属性为null来解决无穷嵌套的问题;针对自定义函数,我通过在预处理阶段,通过预处理阶段的表达式替换的方法来支持自定义函数。
//main函数中的主要处理流程更新
functionGet();
input = preTreat(input);
input = functionTreat(input);
Poly poly = parser(input);
poly.printPoly;
//数据的架构更新
public class Mono {
private BigInteger coe;
private BigInteger exp;
private Poly expPoly;
}
hw3:第三次迭代要求我们支持求导以及自定义函数在定义时调用其他自定义函数。通过在parser类中新增对求导因子的解析方法;通过在读入自定义函数时,额外调用一次自定义函数替换的方法来处理自定义函数的调用。
//main函数中的主要处理流程更新
functionGet();
function.functionString = functionTreat(function.functionString);
input = preTreat(input);
input = functionTreat(input);
Poly poly = parser(input);
poly.printPoly;
//数据的架构无更新
hw1:在第一次作业中,由于架构简单,在进行了充分的本地测试后并没有出现bug。
hw2:在第二次作业中,出现了两个bug,第一个bug是由于过度化简导致的括号丢失,如 exp((-x^2)) 被错误的化简为 exp(-x^2) ,通过更改输出逻辑即可恢复;第二个bug是由于数据结构的递归调用不当而导致的TLE,在适当简化递归调用后就能解决bug。
hw3:在第三次作业中,由于新增功能在第二次已经进行了足够的铺垫,同时由于第三次作业的本地测试充分,同样没有出现bug。
重视实验课程序。在第一单元第一次作业和第三次作业开始之前,实验课都提供了针对作业很好的设计架构,可以说如果能够在实验课结束后完全吸收实验课的示例代码,会对本单元作业有很好的启发。
多浏览讨论区。讨论区的大佬们针对每次作业都会有良好的项目构思和任务解析,经常浏览收益颇丰。
建立自己的评测机*或者用大佬室友的评测机*对自己的代码进行充分的本地测试。中测数据不能说十分的弱,只能说感觉啥都没测(bushi),因此如果希望在强测和互测中取得好的成绩一定要进行充分的本地测试。