301
社区成员
发帖
与我相关
我的任务
分享
我将整个表达式通过calc方法转化为一个ExpElement,其中包括一个TreeMap,记录表达式各部分,指数函数括号内的部分(指数部分)作为Key,相对应由不含指数函数组成的部分(系数部分)作为Value,而Value其实就是第一次作业中转化成的多项式形式Element,由一个TreeMap组成,指数部分为x的指数,作Key;系数部分作Value.
整体类的设计偏多,在迭代过程中增加方法需要考虑的循环较多,对递归不熟练的话可能迭代进展较慢,还有可能造成性能差等问题。但这样的设计也有好处,就是在第一次作业的基础上,之前的部分几乎不需要做任何改动就可以继续第二次作业,在第二次作业中,之前的方法也得到了充分利用。


可以观察到我的类复杂度还是维持在较低水平,但部分方法复杂度较高,可能是由于我在编写方法代码时所使用算法较为繁琐,方法还有待进一步优化。
对于架构方面,首先贯穿各次作业的是lexer文法解析和Parser语法解析,当然在后两次作业中要先进行自定义函数读入的预处理。lexer文法解析的任务在我的程序中说白了就是将读入分块化,一个字符(如+、x)是一个curtoken,一整个数字(如123、36727)也是一个curtoken。这样方便我们后续的处理,比如解析到数字因子时就可以直接把当前curtoken转化成数字并返回。
对于其他部分,在第一次作业中由于没有指数函数,我便采用Element类作为基本项,里面有一个TreeMap记录每一项的系数(Value)和指数(Key),在解析完表达式后我就将解析后的表达式转化为Element,最后再将Element转化为输出的字符串。而后续作业中,我使用ExpElement类作为基本项,其原理在上文中已有介绍。
最后一次作业我的架构基本没有改动,只添加了DaoFactor类并在Parser解析中加入了求导因子,在ExpElement计算中加入了求导计算。
我认为如果再加入三角函数或引入y、z变量,我的方法进行迭代就略显吃力,虽然原来的基础上改动少,但新加的内容较多,递归调用也更复杂,性能较差。且对于新加内容要额外建立新的层次,层次较多,逻辑上相对没那么清晰。但好处依然是将之前的代码最大化利用,迭代思路比较明确。
得益于较为清晰的结构和较为全面的测试,我的程序在三次强测和互测中未出现bug,但在前期评测时还是出了不少bug,最让我印象深刻的就是关于方法编写以及深浅拷贝的问题。第一个方法编写,我在加减法的方法中,总是把this的容器和other的容器弄混,导致一直出现运行时错误,调试了很久才发现;而深浅拷贝更是老生常谈的问题,对于不是本方法想改变的变量或别的类的变量,本方法一定不要改变,返回的一定是新创建的变量,否则会影响传入的变量,导致问题出现。
分析发现经常容易出bug的方法通常复杂度较高,说明可能拆分做的不够充分,造成复杂度较高,若想避免这种情况可以根据用处对方法进行进一步拆分。
在互测中我们需要找出别人代码的bug,对于找别人的bug主要采取三种策略,一是测一下经典问题,比如exp((-x))看他会不会把括号去掉;二是读一下他代码的关键方法,针对方法中可能出现的bug进行攻击;三是使用评测机手段广泛攻击(不过我是使用同学的)。三种方法均有可能发现bug。
对于优化化简我主要只做了两部分,一是有效长度的优化,去掉不必要的多于括号,采取的方法是先无脑套两层括号,最后再遍历分析exp(())里面的东西是否是一个因子,如果是一个因子那只需要一层括号,否则需要两层。还有就是对于性能的优化,我发现代码在运行某些数据时明显过慢,后来同学提醒是因为toString()方法导致运行时间较长,如不优化可能在强测或互测中导致Tle,于是便减少了toString()使用,优化了时间性能。
在优化中我对于原先复杂的方法没有增加内容,而是新增了一个专门用于优化的方法,不影响之前的过程进行,减少出错的可能。也符合单一职责原则。
在本单元学习初期可谓一筹莫展,由于本身对递归理解较差,在刚接触递归下降时很不理解,导致第一次作业就很崩溃。后来与同学交流,他们也简单分享了思路,在交流中我渐渐体会到了递归下降的思想,各部分只需要做好自己的事情,而里层的事只需要调用里层的方法,交给他进一步处理,这样就让整个代码框架很清晰,也让人更容易理解。
通过学习我也学到了提前的文法以及语法解析,这为后面的工作减少了不少工作量,这种思想对后续的学习工作也会起到启示作用。
第二次作业相对第一次更是难度激增,刚开始面对加入的自定义函数以及指数函数不知道如何下手,尤其是基本项的确定让我头疼,但在思来想去后决定第一次架构不改变,在此基础上新增ExpElement类,用以保存指数函数相关相,而自定义函数则是先预处理,将定义式保存,再在解析表达式时解析到自定义函数因子时再进行替换,这样其他地方就不用做出改变。
总之第一单元的作业难度还是比较大,需要系统的考虑架构以及后续可扩展性,需要周中几天持续的努力,但我们也能在其中学到很多
关于第一单元课程的优化,建议任务分配更合理一点吧,如今的难度已经比较合理,但第二次作业相对第一次难度还是增加的比较大,一时可能难以接受,而第三次作业增加内容却难度较小,容易完成,所以建议更合理的分配这两次作业的难度。