一、程序结构分析:
第一次作业:
思路:
1. 建立单项式类,负责使用正则表达式将一个单项式字符串解析为一个单项式,并将系数和指数存储起来,同时设有求导方法。
2. 建立多项式类,负责使用正则表达式将一个多项式字符串解析为多个单项式,通过调用单项式类的解析方法将数据以HashMap的形式存储起来,再调用单项式类的求导方法完成对多项式的求导。
3. 建立主类,负责输入输出并通过实例化多项式对象并调用其方法完成程序功能。
类图:
代码行数:
第二次作业:
1. 建立三种因子类分别存储幂函数、正弦函数和余弦函数的指数,并设有通过解析相应字符串设置指数的方法。
2. 建立单项式类,内有幂函数、正弦函数、余弦函数和常数四个域,可以通过解析单项式字符串来设置这四个域,同时重写了toString方法。此外该类还设有相加方法,以对能合并的单项式进行合并。
3. 建立多项式类,在第一次作业的基础上重写了toString方法,其核心部分是循环调用单项式类的toString方法。
4. 建立化简类,将多项式中的各个单项式尝试提取公因式后,对形如sin2+cos2、1-sin2、1-cos2的形式进行化简合并。
5. 建立求导类,将多项式中的各个单项式进行求导后相加,从而建立求导后的新的多项式,再调用其toString方法完成求导。
6. 建立主类,与第一次作业类似。
第三次作业:
1. 建立因子接口,内置求导方法和toString方法,再建立四种因子类实现因子接口。
2. 建立运算规则接口,内置求导方法和toString方法,再建立加减、乘法、复合三种运算规则类实现运算规则接口,同时也让四种因子类实现运算规则接口(这样在构建表达式树时更方便)。
3. 建立字符串解析类,内置树创建方法,将多项式分解为若干单项式,对单项式的第一个因子创建一个节点,再对剩余部分进行递归调用,完成对树的构建。
4. 建立主类,与上两次作业类似。
二、Bug分析
自我程序寻找bug:
本菜鸡在三次作业中始终使用人工构造测试数据的方法(第一次研讨课有大佬分享自己构建评测机的方法,奈何自己太菜始终get不到要点,自己百度也毫无头绪),通过遍历讨论区以及广大水群来寻找易错点,并构建对应测试数据。
然而人工构建测试数据的方法还是有一定的局限性,如果程序有良好的设计的话还好,但当程序结构的复杂度、耦合度较大时效果就十分有限了。
第一次作业和第二次作业由于设计时各个模块的耦合性较低,互测和强测均没有出现bug;但进入第三次作业之后,无论强测还是互测都爆炸了,因为在一个类中将一整个表达式字符串构建为表达式树,解析过程太过复杂;同时输入的预处理部分和字符串解析部分都含有对WF的判断,耦合度较高。
寻找他人bug:
在互测过程中使用自己在debug过程中构造的典型测试数据,以及另外自己随机构建的一些一般样例对他人的代码进行测试。
(事实证明这种方法完全随缘,要成为一个合格的杀手,还是要学习构建自动评测机。)
三、感想
结构设计:
第三次作业惨痛的教训证明动手之前良好的构思真的很重要(当年学计组的时候也深有同感,但第三次作业由于时间原因没有贯彻落实实属惭愧),例如通过工厂模式对输入的字符串创建相应的对象,能很好的降低模块间的耦合度。在开始动手码代码前,即使花一天的时间构思也不为过,因为这一天的构思能让之后实现各个模块功能时有着事半功倍的效果。
单元收获:
经过了一个单元的学习,我从一个java小白变成了能了解容器、正则表达式、设计模式的基本使用的菜鸡,总体来说收获挺多。更重要的是能尽量从面向对象的角度设计程序,虽然有时候对有些抽象功能还是无能为力,但已经能体会到面向对象程序设计的复杂度低,模块化,可重复利用等特点。在今后的课程中我一定向着理解面向对象思想的方向努力,让自己的代码结构层次更加清晰易懂,能将所学知识真正转化为自己的能力来运用,提高自己的竞争力。