OO-2021 第一单元总结
一、程序结构与OO度量
第一次作业
(1)设计思路
数据结构:
根据直觉和文法,按照表达式-项-因子的层次设计了数据结构。其中,<因子>存储形式为 类型-值,为后续增加新类型因子留下余地,<项>则是一个<因子>的ArrayList,而表达式则是<项>的ArrayList。
输入处理:
因为本次作业没有错误的输入格式,因此对数据进行了预处理,清除所有空格、并将连续的+/-号合并为一个+/-号。

构建了Parser类负责分析语法成分,按照层次构造分析的方法,并且根据层次进行调用。getExpression(), getTerm(), getFactor()分别对应了解析表达式、项和银子的方法。上一层语法层次会调用下一层。
计算化简与求导:
本次作业的计算化简和求导的方法在三个数据结构类中分别实现,根据计算规则,因子间支持乘法multiply(), 而项之间则支持加法add()。由于只有一个表达式,表达式的运算和多个项之间运算并没有本质区别,因此没有实现表达式类的运算方法。此外,由于求导规则较为简单,也没有采用逐层调用的方式,而是在表达式和项一级就实现了功能,因子的求导方法并没有具体实现。
(2)类图
除了用于测试的主函数类test,有四个其他类:
Parser: 负责输入的语法成分分析,将结果存到设计好的数据结构中。
Expression:负责表达式的存储、化简和输出。
Term: 负责项的存储、计算、化简、求导和输出。
Factor: 负责因子的存储、计算、求导和输出。
具体的属性、方法和类图如下:

(3)OO度量
类:

方法:

第二次作业
(1)设计思路
数据结构:
总体改动不大。对于新增的因子类型cos和sin, 只需要改变相应的type值即可。而对于带有括号的复合表达式,会被转化成不含括号的和上次作业一样的“简单表达式”。
而由于括号的出现,因子、表达式、项的语法分析结果均需要用表达式类存储处理。
输入处理:
最大的变化在于括号的出现,使得因子中可能嵌套表达式。因此本次作业参考了编译语法分析中的递归子程序法,对带括号的部分进行递归调用。如下图所示,getFactor()中会递归调用getExpression()。

计算化简与求导:
第一次作业的计算化简和求导的方法在三个数据结构类中分别实现。而本次作业的计算化简更加复杂,因此单独实现了Cal类,通过重载实现各类型之间的乘法和加法。
求导则依旧在三个类中通过调用下一层的求导方法实现。
在求导与运算的过程中,会在计算前后调用化简方法,以期最后的结果长度最短。
(2)类图
除了用于测试的主函数类test,有五个其他类:
Cal: 实现了表达式、因子、项之间的乘法和加法。
Parser: 负责输入的语法成分分析,将结果存到设计好的数据结构中。增加了递归调用。
Expression:负责表达式的存储、化简和输出。
Term: 负责项的存储、求导和输出。
Factor: 负责因子的存储、求导和输出。

(3)OO度量
类:
方法:


第三次作业
(1)设计思路
数据结构:
总体改动不大。因为sin和cos表达式括号中的内容不再固定为‘x’, 因此增加了因子的属性"str"来记录三角函数括号中的内容
输入处理:
增加了格式检查的环节。先按照文法对输入进行了语法检查,再进行预处理,只需在原有的直接获取内容的分析方法中加入判定即可。由于作业并不考虑时间上的性能,采取了“多遍”的形式,没有将语法检查和分析一同进行。
计算化简与求导:
除了在计算中保留sin和cos函数括号内的内容,并没有其他大的改动。
(2)类图
除了用于测试的主函数类test,有五个其他类:
Cal: 实现了表达式、因子、项之间的乘法和加法。
Parser: 负责输入的语法成分分析,将结果存到设计好的数据结构中。增加了语法检查。
Expression:负责表达式的存储、化简和输出。
Term: 负责项的存储、求导和输出。
Factor: 负责因子的存储、求导和输出。
(3)OO度量
类:

方法:


二、自己程序的BUG
第一次作业在强测和互测中出现了RuntimeError。
推测出现原因为Parser读取输入的循环终止条件有问题。
第二、三次作业互测和强测均未被发现bug。
三、互测发现的BUG
因为个人精力有限,只能关心自己的程序,并未参与互测。
四、重构
由于第一次作业中就划分了层次,并为后续扩展留下了一定的空间,因此总体上改变并不是很大,唯一一次较大的重构是在第二次作业中:
为了降低类的复杂度和耦合性,并提高可读性,将各个类间计算的方法从各个类中移到统一的Cal类中。这同时也方便了重载、测试等环节的进行。


五、心得体会
首先,我收获了很多。通过这个单元的学习,我对面向对象思想有了较为深入的理解,并掌握了递归、正则表达式等工具的运用。
但需要改进的地方也还有很多。由于个人原因,我对代码风格、互测等环节无暇顾及,好在后两次强测结果都是90+,还算不错。争取以后有机会深入参与互测,改进代码风格。

浙公网安备 33010602011771号