301
社区成员
发帖
与我相关
我的任务
分享unit 1 主要完成了表达式的解析,展开,化简和求导。
表达式的解析采用的递归下降,在解析的过程中将表达式展开,再将展开后的式子化简。在最后一次作业中,完成求导功能。
第一次作业我觉得是最有思考量的,因为它是一个从无到有的过程,比如如何解析表达式,如何增加因子,项,如何化简等等。以下是我的uml类图

架构分析:
我是在training1架构上进行迭代的,
lexer是词法分析,主要是识别读到的每个词代表的含义,比如括号,常量因子,变量等等,parser则将词法读入的内容进行解析和展开,用Expr- >Term->Factor的结构进行递归下降。
复杂度分析:

可以看到,比较复杂的是addExprFactor,因为我在加表达式因子的时候,需要和之前的因子相乘并展开,需要遍历因子和现有表达式因子,还有就是printPolynomial,我是将一个项化简后的次数和系数存到一个hashmap里,然后根据hashmap里的数进行化简。
bug分析与优化:
在一个循环中,我把循环的信号放到了循环里面,导致每一次都会被初始化,原因在于本地测试不充分,过了中测就没管了
第二次作业是代码量最多的一次,新增因子expFactor,并增加自定义函数,其中自定义函数可以嵌套调用。uml图如下

函数的调用整体难度不大,要注意的一个点是存储自定义函数的funcmap 需要把参数替换一下,不然会出现问题,例子如下
f(x,y) = x + y f(y,3*y)
存储的时候把x缓存a,y传承b,z换成c,注意最后把eap换成exp。
expFactor 引入,以及变量xyz的引入,让之前的Hashmap存储系数指数方法变得不可行,于是我把每一个项转化成mono的格式,
public class Mono {
private BigInteger coefficient;
private BigInteger powerExponentX;
private BigInteger powerExponentY;
private BigInteger powerExponentZ;
private String exponent;
}
再对比系数化简,输出。
复杂度分析:


复杂度比较大的是printmonos,主要是if的判断条件比较多,还有exp(0)= 1,输出为空的时候输出0等特殊状况。
另外还有问题是解析时递归以及addfactor时循环耗时
bug分析与优化:
上次作业划分expression的方式不适用于多层括号,我没有改,其实还是本地测试不够充分,另外还有addFactor时每次都要遍历现有因子,造成了tle
第三次作业比起前两次难度较小,增加求导功能,我的实现方式是,把求导当作一个因子,如果识别到dx,对括号里面的表达式解析,由于每一项都可以转化成mono的形式,所以求导结果可以根据mono的各属性直接写,对于exp里的表达式,在循环调用求导解析就可以了

复杂度分析:
其实复杂度和第二次作业差不多,主要还是解析时的递归调用,和printmonos时遍历输出。


bug分析与优化:
这次bug主要是RE和CPU limited,主要是解析表达式展开的时候,每次都要遍历现有因子,再乘进去,表达式越长耗时越长,改进方法是,边解析边化简,相同项直接在解析的时候就合并。
测试策略:
第三次作业开始我用的评测机,但显然评测机不是万能的,边缘数据和特殊数据还是需要自己造。
好的架构真的很重要,不然面临新的任务就需要重构重构再重构,建议是可以去参考往年博客的优秀框架,建立一个易于迭代的架构。另外,比起oopre,oo对性能的要求更高了,如果代码性能差,在强测和互测环节真的会很惨,这也是我下一单元需要加强的。
或许可以在第一次作业的时候,让同学对这一单元的架构有个初步设计与构思。