OO第一单元——表达式求导——总结

摘要:
大二的第一个月即将结束,OO的第一个单元也结束了。这里是我第一个面向对象单元的总结。总的来说,第一个单元有三个操作,即:多项式推导、幂函数和三角函数表达式推导和嵌套表达式推导。第三个结构第三个作业基本上继承了我的第二个结构我的整个结构分为三层:ExpressionTermFactorPowFuncTriFuncConstantExpFactor,其中Factor是每个层的接口,ArrayList用于记录下一层的引用。

大二下的第一个月就要结束了,OO的第一单元也结束了,因此在这里总结一下我的OO的第一单元的情况。

总体

第一单元有三次(不计寒假pre)作业,分别为:多项式求导,带有幂函数、三角函数的表达式求导 和 带嵌套的表达式求导。
我三次作业的结构都不完全一样,其中第一次和后两次完全不一样,第三次基本沿袭第二次。下面,我review一下我每次的结构。

结构

第一次

结构

first-art

第一次的结构比较简单,基本就是使用HashMap记录每个次幂的系数,然后Poly求导时调用Term的求导方法即可。

耦合度

classOCavgWMC
InputFormatWrong1.02.0
Poly3.521.0
Term2.323.0
TermAddPowDifferent1.03.0
Total49.0
Average2.333333333333333512.25

第二次

second-art

第二次作业我的总体结构分为了三层:

  • Expression
  • Term
  • Factor
    • PowFunc
    • TriFunc
    • Constant

其中,Factor是一个抽象类(现在想来,使用接口更好)

每一层,使用ArrayList记录下一层的引用。

加法求导直接调用下一层即可。

乘法求导使用链式法则。

输出部分,为了拓展性,我使用专门的Outputer类进行的输出,里面使用了Quad和Triad两个类进行优化,这两个类重写了equals,hashCode,comparaTo等方法,使用hashMap合并。

耦合度

classOCavgWMC
Expression2.307692307692307530.0
Factor1.03.0
InputFormatWrongException1.02.0
Main2.02.0
Number1.14285714285714288.0
Outputer7.2529.0
PowFunc1.571428571428571411.0
Quad1.916666666666666723.0
Term2.2527.0
Triad2.016.0
TriFunc2.12517.0
Total168.0
Average2.181818181818181714.0

这次作业我专门花了大量时间设计了结构因此整体耦合度相比第一次好看了许多。不是很好的时Outputer类,这里有大量的优化代码,优化代码写的不够优美,因此我还需要更多练习。

第三次

结构

third-art

第三次作业基本继承了我第二次的结构

我的总体结构分为了三层:

  • Expression
  • Term
  • Factor
    • PowFunc
    • TriFunc
    • Constant
    • ExpFactor

其中,Factor是一个接口

每一层,使用ArrayList记录下一层的引用。

TriFUnc有一个Term的引用

ExpFac有一个Exp的引用

综上,我的结构基本符合文法

加法求导直接调用下一层即可。

乘法求导使用链式法则。

输出部分,我重写了toString方法

耦合度分析

methodev(G)iv(G)v(G)
Builder.build(String)3.02.04.0
Builder.readExp(String,ArrayList)4.04.07.0
Builder.readFactor(String,ArrayList)9.07.010.0
Builder.readTerm(String,ArrayList,BigInteger)4.06.07.0
Builder.triMatch(String,ArrayList,Matcher,int)4.02.04.0
Constant.calcDerivative()1.01.01.0
Constant.Constant()1.01.01.0
Constant.Constant(BigInteger)1.01.01.0
Constant.Constant(String)1.01.01.0
Constant.getValue()1.01.01.0
Constant.toString()2.01.02.0
ExpFac.calcDerivative()1.01.01.0
ExpFac.ExpFac(Expression)1.01.01.0
ExpFac.getExp()1.01.01.0
ExpFac.isIn(String)5.04.08.0
ExpFac.toString()3.02.04.0
Expression.add(Expression)1.01.01.0
Expression.add(Term)1.01.01.0
Expression.addTerm(Term)1.01.01.0
Expression.calcDerivative()1.02.02.0
Expression.Expression()1.01.01.0
Expression.Expression(ArrayList)1.02.02.0
Expression.Expression(Term)1.01.01.0
Expression.merged()1.01.01.0
Expression.multiply(Expression)1.01.01.0
Expression.multiply(Term)1.01.01.0
Expression.toString()1.05.07.0
InputFormatWrongException.getSituation()1.01.01.0
InputFormatWrongException.InputFormatWrongException(String)1.01.01.0
Main.main(String[])2.03.04.0
PowFunc.calcDerivative()1.01.01.0
PowFunc.getPow()1.01.01.0
PowFunc.PowFunc()1.01.01.0
PowFunc.PowFunc(BigInteger)1.01.01.0
PowFunc.toString()3.03.03.0
Quad.compareTo(Quad)3.03.03.0
Quad.equals(Object)6.02.06.0
Quad.getArr()1.01.01.0
Quad.getFirst()1.01.01.0
Quad.getForth()1.01.01.0
Quad.getSecond()1.01.01.0
Quad.getThird()1.01.01.0
Quad.hashCode()1.02.02.0
Quad.merge(Quad)1.02.02.0
Quad.Quad(BigInteger,BigInteger,BigInteger,BigInteger)1.01.01.0
Quad.Quad(BigInteger,Triad)1.01.01.0
Quad.Quad(BigInteger[])2.01.03.0
Term.addFactor(Factor)1.01.01.0
Term.calcDerivative()1.02.02.0
Term.multiply(Factor)1.01.01.0
Term.multiply(Term)1.01.01.0
Term.Term()1.01.01.0
Term.Term(ArrayList)1.02.02.0
Term.Term(Factor)1.01.01.0
Term.toString()1.03.05.0
Triad.equals(Object)6.02.06.0
Triad.getArr()1.01.01.0
Triad.getFisrt()1.01.01.0
Triad.getSecond()1.01.01.0
Triad.getThird()1.01.01.0
Triad.hashCode()1.02.02.0
Triad.Triad(BigInteger,BigInteger,BigInteger)1.01.01.0
Triad.Triad(BigInteger[])2.01.03.0
TriFunc.calcDerivative()1.02.02.0
TriFunc.getPow()1.01.01.0
TriFunc.getType()1.01.01.0
TriFunc.getVal()1.01.01.0
TriFunc.toString()3.03.05.0
TriFunc.TriFunc(int,Factor,BigInteger)1.01.01.0
Total114.0113.0150.0
Average1.65217391304347831.63768115942028982.1739130434782608
classOCavgWMC
Builder6.432.0
Constant1.16666666666666677.0
ExpFac2.814.0
Expression1.636363636363636518.0
InputFormatWrongException1.02.0
Main2.02.0
PowFunc1.47.0
Term1.7514.0
TriFunc1.833333333333333311.0
Total146.0
Average2.115942028985507312.166666666666666

可以看出,我的builder写的不是很尽人意,不过由于这是读入部分,内部耦合度的确会很高。综合来看,这次的情况比上次好了许多,我也的确感觉自己的结构优美了、“面向对象”了很多

BUG

我没有在公测和互测中被发现BUG

从中我大概总结如下:

  1. 设计结构时让结构优美
  2. 写代码时认真思考
  3. 写代码时符合标准,代码风格需要优美
  4. 写完后测试所有样例
  5. 认真手动构造极限的样例
  6. 使用自动化测试测试自己的代码(跑一天以上)
  7. ……

同时,我也看了其他同学的代码,发现了一些印象深刻的代码,大概如下

  1. 优化写错
    • 个人认为,如果结构设计的够好,优化部分也是可以写起来很简单的。比如如果写足了表达式的乘、加等方法,在优化的时候调用就好,切忌面向过程地优化
  2. 读入写错
    • 读入是一个十分值得测试的部分,交作业前在进行测试的时候,一定要做到充分的,全面的测试。

关于创建模式

创建模式看起来十分深奥,在我简单的理解起来,大概是一个在选择创建一个父类的多个子类的时候,让子类的选择交给一个的一个方法。这样,可以降低代码的耦合度。

就是说,我的一个类的判断,只负责判断一层。

这次,我在对象创建的时候,我专门实现了一个builder类,builder类内有三个方法,分别识别Exp,Term,Factor。现在看起来,我可以把这三个方法拆开,分别识别一个类,这样降低耦合度。

感想

第一个月刚刚过去,表达式求值也是我写的第一个系统的java的工程。可能目前我对面向对象和java的理解还不够深入,但我相信在不断的OO课程的学习和练习中,对这方面的理解会越来越深入。

感谢为这门课程付出的老师和助教们。

免责声明:文章转载自《OO第一单元——表达式求导——总结》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇[WPF] 如何调试Data BindingnRF52832 开发记录(二)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

intellij idea 显示Arraylist 扩容过程 解决not showing null elements

设置显示Arraylist中的null完整查看初始数组大小,扩容过程一、老版本:Settings -> Debugger -> Data Views -> Arrays -> Hide null array elements新版本:Settings -> Debugger -> Data Views -> Java...

梯度出现Nan值的追踪

1. torch.autograd.detect_anomaly()转自点击 , import torch # 正向传播时:开启自动求导的异常侦测 torch.autograd.set_detect_anomaly(True) # 反向传播时:在求导时开启侦测 with torch.autograd.detect_anomaly(): loss....

Array和ArrayList的Clone为什么一个不用类型转换,一个要类型转换

通过上面一段代码可以看出Array的Clone()不用进行类型转换,但ArrayList的Clone要进行类型转换。为什么会出现这种情况呢?我们来分析下源码 现在来看下Array的Clone()方法源码 发现Array里没有Clone()方法,调用的都是Object里的方法 这里面的除了Object并不是说Object就不遵守这个惯例,而是Objec...

java8使用parallelStream并行流造成数据丢失或下标越界异常解决方案

描述 我们先看一段使用了并行流的代码 @Test public void testStream() { List<Integer> list = new ArrayList<>(); for (int i = 0; i < 10000; i++) { li...

【数据结构与算法】用go语言实现数组结构及其操作

引言   数组结构是一种很常见的数据结构,并且在大部分编程语言中都存在,这些语言都提供了现成的可以立马就能使用的数组这种数据结构。为了更好的理解数组,这边文章就是来实现数组。 数组的特点   1.内存中数据之间紧密排列在一起。   2.新增元素需要开辟内存空间用以存放新的元素。   3.新增元素时候,如果新增的元素在其他元素中间,那么该新增元素的位置后面所...

Arraylist(变长list) 及 定长list的基本使用

1. 定义arraylist并添加值 ArrayList<Integer> obj = new ArrayList<>(); for (int i = 0; i < 6; i++) { obj.add(33); }注: <Integer>中规定了arraylist中的元素类型,只能放规定类型的元素. 可以...