301
社区成员
发帖
与我相关
我的任务
分享本次作业,我的所有架构都围绕着四步进行:展开、标准化、合并、简化

下面,我将讲述我是如何围绕着这四步进行程序的设计,我的设计又存在着哪些问题
读入模块
我的输入部分主要采用了实验代码提供的架构,即通过lexer和phaser进行配合读取表达式中的信息
这种方法的好处在于:
符合递归下降的定义,便于理解
层次下降,没有冗余的步骤
我认为它存在的一个缺陷是初始模板过于固定,没有将各个类的读取方法统一拆分出来,导致后期加入exp和dx等因子时需要修改原有代码,不符合oo原则
展开模块

我在展开中也采用了 递归下降的思想,即“应展尽展”
在HW2之前,我这步具体实现方法为遍历每一个Term,并将其中的表达式因子相乘,将其余因子作为系数乘到最后的表达式中,得到展开后的表达式(此时,表达式中应当无表达式因子)
HW3添加了两个会造成困难的东西:
求导
我选择直接在展开部分完成求导,按照链式求导法则将表达式一步步化简
自定义函数嵌套
由于我处理函数嵌套的方法是将所用的自定义函数用字符串形式展开,所以天然能够处理嵌套问题
标准化模块

一个表达式的标准形式应当是:
$$
expr = num*vari*exp()
$$
在展开中,我们已经做到删除式子中的表达式因子,因此这步只需要将相同类型的因子相乘合并,将不同类型的因子补全,即可完成操作
合并模块

合并这步有三种常规方法:Hash、String…和暴力
我选择暴力!!
如何让名义上O(n^2)的暴力变得简单一些呢,为此我对每个Term维护了一个HashSet,这里面包含了在从前和以后所有的时间中,和Term保证已经不同的Term的引用
也就是说,在全局中,两个Term之间的比较只会出现一次,这样就大大减少了时间开销,使得合并和简化效率飞快
简化模块

在这步,我们需要根据表达式的具体形态删去一些因子(比如1和x^0)
通过一系列逻辑判断后,我们就得到了最终完美的式子
性能模块
很遗憾,拓欧调试了两天没调对(真的很遗憾)
可恶,U2再战!!
bug
凡是zlr同志写的代码,我们都一律认为正确
凡是zlr同志写的bug,我们都一律不hack(新时代两个凡是
bug啊,很多的啦…(目移
我在hw2和hw3的互测中都为房友送了分:
hw2
当输出exp((-x))时,我的程序会将其简化为exp(-x)
这个bug的产生有很复杂的架构原因(),需要特判解决
hw3
当输出exp((-exp(x)))时,我的程序会将其简化为exp(-exp(x))
可以发现和hw2本质上是一模一样的bug
心得体会
不甘心,我不甘心啊(
建议
给予性能分更多的分数,这样才能群魔乱舞(bushi