BUAA OO第一单元总结

# <div align = "center">OO第一单元总结</div>

## 一、程序结构分析

### 1.1 HW1

#### 1.1.1 构建思路描述

本次作业除了MainClass外,实现了十个类加一个Facter接口。我的设计思路如下:

* 首先采用递归下降的方法分析输入表达式,得到后缀表达式,再利用Simplify类进行计算、化简、合并,最后得到一个Poly类的对象,里面包含了每一项的系数与三个变量的指数,最后通过toString()输出即可。

* 我是通过训练栏目获得的思路,得到的后缀表达式每读到一个运算符就按照运算符的逻辑关系将其前两项进行运算即可,Poly即多项式类里实现了add、sub、mul方法,VaryPow即项类里实现了项与项之间的add、sub、mul方法和判断两个项是否能够合并的judge方法,这样在进行表达式和表达式之间的运算时直接调用项与项之间的运算方法即可完成。

​我的后两次作业也是基于分析后缀表达式从而得到a*x**(x的系数)*y**(y的系数)*z**(z的系数)形式的项(VaryPow),再通过Poly间的运算进行处理的方法。

#### 1.1.2 UML图

![img](https://img-community.csdnimg.cn/images/e395584fba5049d2b44b34145f244e51.png "#left")

Lexer类和Parser类实现递归下降解析表达式,Simplify类用来化简合并表达式类,VaryPow是项类,规定了每个项的系数与指数以及实现了项与项之间的运算规则,Poly是表达式类,用来存储化简过程中得到的expr并且实现了expr间的运算方法,通过调用VaryPow的运算方法来实现相互调用。

#### 1.1.3 类复杂图

![img](https://img-community.csdnimg.cn/images/7c3d399158744745acc8d926156ede6e.png "#left")

#### 1.1.4 方法复杂图

![img](https://img-community.csdnimg.cn/images/20d42ff272cf4a569df2fcaf9672d855.png "#left")

![img](https://img-community.csdnimg.cn/images/cca6d84c65dc4b3585d0b7259c1cf04c.png "#left")

### 1.2 HW2

#### 1.2.1 构建思路描述

​第二次比第一次多了三角函数sin和cos,还有自定义函数。基于第一次作业的框架,这次只需要在项VaryPow里加一个三角函数的内容即可,得到a*x*y*z*sin*cos的形式;新加一个自定义函数类,先递归下降将表达式里的自定义函数全都replace,再递归下降处理之后得到的不含自定义函数的表达式得到后缀表达式进行计算即可,此时就回到了第一次作业的流程。

​但是这次作业我没有充分考虑架构的可扩展性,比如我在VaryPow里加三角函数内容的时候是直接用字符串表示了,HashMap<String, BigInteger> String即为sin()或者cos(),BigInteger为系数,这也导致我在第三次作业需要对三角函数求导的时候无处下手,只能被迫小型重构。

#### 1.2.2 UML图

![img](https://img-community.csdnimg.cn/images/bf1995fbd0dd46d49e3534fb040c484b.png "#left")

#### 1.2.3 类复杂图

![img](https://img-community.csdnimg.cn/images/ebbff02fd1b448b2b254bdac3d1d9f6f.png "#left")

#### 1.2.4 方法复杂图

![img](https://img-community.csdnimg.cn/images/fa593b25469d4326994937e908cefedd.png "#left")

![img](https://img-community.csdnimg.cn/images/09811d7327da481084b8c72515e731a2.png "#left")

### 1.3 HW3

#### 1.3.1 构建思路描述

​由于我在第二次作业实现上偷了懒,没有充分考虑到架构的可迭代性,导致我被迫进行小范围的重构。这次作业我在实现三角函数项时,HashMap<Poly, Pair<BigInteger, Boolean>>来存储三角函数项,这样即可实现对三角函数嵌套形式的求导,Poly是该三角函数括号里的内容,Boolean是0代表是sin,1代表cos,另一个是系数,而且该种形式方便进行三角函数的优化合并。

​而在第二次作业我对自定义函数也是直接进行String层次的拆分,没有考虑到这次的自定义函数中调用自定义函数,所以变换了处理策略:即将自定义函数读取时也利用递归下降来分析,进行代换,这样就可以在第二次架构的基础上直接在表达式中进行代换。

​我在VaryPow和Poly两个类里均实现了求导方法,这样VaryPow的三角函数对其含有的Poly求导就可以调用Poly的求导方法,而Poly求导就可以分别对其中含有的每一项VaryPow求导然后相加即可,这种相互调用进行求导体现了层次化思想.

#### 1.3.2 UML图

![img](https://img-community.csdnimg.cn/images/8c059c3703c7463abc3d698b66d01988.png "#left")

#### 1.3.3 类复杂图

![img](https://img-community.csdnimg.cn/images/89cdfebd147e42f09648e86b5528c6b2.png "#left")

#### 1.3.4 方法复杂图

![img](https://img-community.csdnimg.cn/images/82ea49d85cf54e5cad977ff1ef7830a2.png "#left")

![img](https://img-community.csdnimg.cn/images/cdf2433b7f7e40489bedd492c93a2e62.png "#left")

## 二、Bug分析

​第一次作业:由于我一时疏忽,在处理数字时有一处使用的是Long类型存储,最后忘记更改成BigInteger,导致互测时被大数hack;还有在多项式和多项式进行加法运算时,没有处理“爆0”,即如果运算之后是0就不应该添加到我们的结果中,因为最后可能会因为结果中出现大量的“0”而超时,所以特判一下即可。

​第二次作业:这次作业被hack的有点惨,被hack了15处,但还好最后修复其实就是两处bug:

1. 忽略了称号* 和 **的优先级,在识别出\*或者**后应在项的两边加上括号,否则容易出现计算顺序错误的问题,所以在两边加上括号即可fix;

2. 由于三角函数的出现,我在第一次架构中忘记了两个多项式加完之后是0的问题,导致最后可能出现两个多项式运算玩之后如果是0可能得到的结果是一个空的多项式,即里面什么都没有,如果没有三角函数这影响不到我的最终结果,因为最后在输出时如果长度为0会直接输出0,但是存在sin和cos可能就会出现sin()和cos()的情况,从而出现形式错误。

​第三次作业:这次作业的互测没有被hack到,但是强侧wa了一个点。主要是我没要区分好 判断两个项能否合并和两个项相等 这个概念。一开始没有考虑到三角函数合并时必须要求其括号内含有的expr的系数必须相同,因为我之前写的判断两个项相等的方法实际上是两个项是否能够合并的方法,即没有考虑这两个项系数是否相等,而三角函数若想要合并则必须要求其括号内含有的expr的系数必须相等,因此我添加了一个equal2方法和judge2方法用于判断两个expr或者两个item是否完全相等而不是仅仅能够合并。 如图所示,利用之前写的equal方法x和-x会被看做是相同的,因为他俩除了系数完全相同因此能够合并,而外面加上三角函数就必须要求系数相同才可以进行合并。

![img](https://img-community.csdnimg.cn/images/e07f3d2586fa43a8b9d709aac316d903.png "#left")

## 三、hack策略

​通过阅读他人代码可以学习一些扩展性好的架构,也可以发现一下比较明显的bug,比如有些同学数字的存储没有使用BigInteger,三角函数在优化时可能忽略一些系数和指数的处理,还有一些边界数据的问题。

## 四、架构设计体验

​本单元作业我体会到了面向对象式的层次化设计在处理复杂工程中的优越的可扩展性,递归下降在处理表达式问题的优越性。第一次作业虽然没有括号的嵌套,但是通过递归下降解析就可以应付之后的不同形式的嵌套问题,比如三角函数嵌套、自定义函数嵌套,递归下降就是解决这类问题的“通法”,不论形式有多复杂,都可以递归下降一步步解析出他应有的层次。

​我的架构是在三次作业中一步步走向成熟的。首先从控制台读入表达式后,先进行预处理,去除空白符和连续的"+"或"-",或者多余的"+";然后传入Lexer和Parser进行递归下降解析,最后得到一个Expr类的对象,即后缀表达式,然后利用Simplify类进行运算,Poly类(多项式)里面有个VaryPow(项)的ArrayList容器,最后得到一个Poly类的对象,toString()输出即可;

​第二次作业出现了三角函数和自定义函数,则新添三角函数类实现Factor接口,自定义函数实现Factor接口,参与到表达式的解析;然后对于自定义函数,我的处理是先递归下降处理自定义函数得到不含将其替换,然后再递归下降处理得到的表达式,然后就变成了第一次作业的处理流程,因此这次作业只需在第一次作业的基础上加两个实现了Factor接口的类即可;

​第三次作业出现了求导和自定义函数中调用其他自定义函数,只需要把Varypow里的三角函数容器换下形式、并分别在VaryPow和Poly里实现求导方法即可;而自定义函数也按照递归下降的流程replace一下即可,所以总的来说没有重构什么,由于递归下降的可扩展性,使得我在这三次作业都是一步一步在前一个架构上加一点东西就实现了。

## 五、心得体会

​本单元作业我初步体会到了面向对象设计方法的好处,在面对未知的迭代任务时,建立一个好的架构对于日后的工作可以说是事半功倍.第一次作业由于训练栏目给的启发采用了递归下降的方法来处理表达式得到后缀表达式再进行计算,从而在接下来的两次作业中能够完成增量开发.因此,建立一个好的架构不仅可以减少bug数量,也方便进行优化开发.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值