面向对象与程序设计第一单元总结

徐志衡-21371109 学生 2023-03-19 19:48:21

面向对象与程序设计第一单元总结

一、架构设计

本代码架构如下图所示:

img

本代码与training的代码的核心思路相同,都是采用递归下降的方式,并在此基础上添加了一些内容:

1. 函数的处理:

笔者设计了一个Function类,其中存储了函数的名称,函数的形参,以及函数的形参表达式,即存储了函数的具体信息,这样在将表达式中的函数替换时更加方便。

2. 表达式的预处理:

本人设计了一个Process类,其中的move()函数里采用正则表达式的方法对表达式进行了化简,例如去除连续的+,-,将**暂时变为^,去除*后的带符号的整数因子的符号等,都是为了方便之后的对表达式的处理。

3. 求导的处理

本人将待求导的表达式看作一个新的表达式对其进行处理,并在ExprTerm类里增添了新的函数来处理求导。

4. Factor接口增添新的类Pow

该类存储三角函数和幂函数本身以及次幂,通过第一个字母是s,c还是x,y,z来判断其是三角函数还是幂函数。

优点:

本代码设计了较多的类,便于理解和维护;并且有效地使用了正则表达式,大大简化了后面对表达式的处理。

缺点:

随着hw_1至hw_3的任务的添加,本代码的条理性逐渐降低,使得“面向对象”逐渐有点“面向编程”;没有将三角函数和幂函数存储在两个类里,增大了处理的复杂性。

二、bug分析

1. 因变量代换“有次序”导致错误:

例如如下输入:
1
f(x,y)=x**2+y
f(y,x)
原来代码的变量代换是依次代换,即按顺序将形参替换为实参,但上述情况就会出现问题,将第一个形参x换为实参y后,f的表达式变成y**2+y,再将第二个形参y换为实参x后,f的表达式变成x**2+x,这与期望的结果:y**2+x不同,原因是所有参数替换不能“同时”完成,导致后面的实参错误地替换掉了前面的实参。

解决方案:

代码是按语句依次执行的,不能同时执行多个语句,因此我们将Function类中的形参变量不记为x,y,z,而是记为大写的X,Y,Z,并且将其中的形参表达式中的所有x,y,z也替换为X,Y,Z,这样以上述输入为例,f的表达式是X**2+Y,第一次代换后,f的表达式变成y**2+Y,第二次代换后,f的表达式变成y**2+x,就得到了我们想要的结果。

2. 正则表达式处理有误:

原来代码对于连续的+,-是在Process类的move()函数里,代码如下:
String symbol1 = "(\+|-){2,}";
Pattern pattern1 = Pattern.compile(symbol1);
Matcher matcher1 = pattern1.matcher(str);
while (matcher1.find()) {
str = str.replaceAll("\+\+", "+");
str = str.replaceAll("\+-", "-");
str = str.replaceAll("-\+", "-");
str = str.replaceAll("--", "+");
}
即按照“同正异负”的原理将连续的+,-变为单个的+-,然而当遇到连续三个及以上+,-时,该while只循环了一次,导致没有变为单个的+-,从而产生错误,原因是一轮循环后没有使用新的str

解决方案:

while的最后添加语句:
matcher1 = pattern1.matcher(str);
这样在每次的循环最后就会检查新的str,就成功解决了上述问题。
##三、心得体会
纯纯坐牢 在第一单元的这三次作业中,笔者体会到了“面向对象”与“面向编程”的不同,逐渐感受到了java语言中“对象是类的一个实例”的特点,也感悟到了递归下降的方法的优点:与逆波兰表达式方法不同,该方法逐层解析表达式,易于读懂和维护代码,具有数学上的美观性。

...全文
49 1 打赏 收藏 举报
写回复
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
诸彤宇教师 教师 3天前
  • 打赏
  • 举报
回复

体会到了“面向对象”与“面向编程”的不同
————是什么不同啊

发帖
2023年北航面向对象设计与构造

382

社区成员

2023年北京航空航天大学《面向对象设计与构造》课程博客
java 高校 北京·海淀区
社区管理员
  • 被Taylor淹没的一条鱼
  • 柠栀_Gin
加入社区
帖子事件
创建了帖子
2023-03-19 19:48
社区公告
暂无公告