BUAA OO 第一单元作业总结
BUAA OO 第一单元作业总结
第一次作业
第一次作业由于高估了自己的水平,低估了作业的难度,我没能及时的在作业截止前提交,而我的第二次作业也因为直接在第一次作业上进行修改从而导致第一次作业的代码被覆盖,因此关于这次作业我也只能写写自己一开始构想的思路了。
我的思路主要借鉴了实验课助教提供的项分类代码。
1.首先进行字符串的预处理,将形式混乱的字符串化为较容易处理的形式(去除空白符,消去连续符号,替换**为^)。
2.其次构造Poly类和PolyMap类,在PolyMap类的函数中读取因子,并存入以Poly构造的HashMap中。
3.最后根据实验课的思路输出多项式。
优缺点分析
构建思路很快,处理起来也较为简单。但是未考虑后续优化,导致第二次作业构思时间极长。
第二次作业
重构经历
这次作业的重构构思了很长时间,最终在同学战晨曦评论区的方法帮助下成功敲定了框架。作业一共由三类构成,这也导致耦合度较高。
只保留第一次作业中的Main类,主要功能为化简字符串。
新增Node类,作为表达式树的结点类型,保存左右子树,字符串和求导前后结果。
新增Tree类,主要有createNode方法和derivative方法,分别用于找到符号构建左右结点和求导,分别用了一次递归。
Tree类的createNode方法主要思路为:先找到括号外的第一个加减法,并将其分为找到符号的左右子树,再在左右子树中执行这个过程;当找不到加减法但有括号时,去掉最外层括号,并再按照这个思路构建左右子树;找到单独的数字,幂方,三角函数后停止递归。
Tree类的derivative方法主要思路为:先对左右子树求导,再根据表达式树结点的符号将左右子树的求导结果和原结果结合;当遇到单独的数字,幂方,三角函数后停止递归,直接处理。总的来说和上一个方法相似。
本次作业UML图
度量分析

整体的复杂度主要源于建树和求导的递归调用以及没有为各个类型的结点单独建类。
BUG分析
这次作业在强测和互测阶段都没有出现BUG。而我在互测阶段中找BUG的手法主要为构造括号的嵌套以测试爆栈或TLE等。
优缺点分析
此方法构造思路快,方向明确。但是很难做出优化,容易产生大量冗余括号,同时该架构也无法支持第三次作业,只能再次重构。
第三次作业
重构经历
这次作业是一次大变动,与第二次作业的架构完全不同,在第三次作业中,我采取了递归下降的方法,主要思路如下。
构建Wrong类,在判断格式错误时退出程序并输出。
在Main类中进行格式的初步判断,例如空格的错误,连续符号的错误以及非法字符的错误等,接着再将表达式进行初步化简。
新建Expr,Term,Factor,Pow,SinCos这五大类,分别代表表达式,项,因子,乘方和三角函数。这五个类中都有属性com,dir,index,分别代表未求导的原式,求导后的式子,字符串的下标。
先将字符串送入Expr内进行解析,再一步步递归至其他四类中,同时要维护字符串下标,每次递归完毕后读取下标。在每一类内若出现异常,则直接调用Wrong类内的方法报错。
在处理完字符串后,根据最终返回的下标和字符串长度进行比较,选择报错或输出求导后的式子。
本次作业的UML图
度量分析


本次作业的复杂度主要出自各类中解析自身的方法中,因为需要大量调用递归,并且我在每个类,尤其是三角函数类内加了大量的if判断。其实可以将三角函数的类再细划分,但我为了思维的连贯性还是将它合并成一个类了。
BUG分析
这次的作业在强测的一个点上出了BUG,原因是在因子解析时没有因空字符,加号,减号报错,导致输出了sin(())这样的格式,在添加一层判断后很快就通过了测试。
在互测阶段我也没能找到其他人的BUG,在本地测试了几个人的代码后,没有发现他们的漏洞,也因此自己没有在平台上进行hack提交。
优缺点分析
此方法思路清晰有条理,可以按照给的格式一步步解析,不会出错;化简较表达式树的方法更容易;可维护性强,容易进行功能的拓展;只用遍历一次字符串便可输出答案,用时短。但这样的结构对于下标的维护要求高,同时要明确判断各个情况,编程时一不小心就容易出漏洞。
感想与体会
- 评论区真的十分有用,我的很多构造思路都是参考了评论区内同学的代码才能写出来。同时,同学间的思路交流也更容易拓展自身的想法。
- 最好在一开始就往最后一次作业的架构上靠,因为正确的架构是简洁而又方便的,比一开始自己瞎构想的架构要靠谱很多。
- 不要害怕重构,每次重构都是对自己思维能力的提升。

浙公网安备 33010602011771号