面向对象第一单元个人总结

 

面向对象第一单元个人总结

 这次主要依据作业要求中的四个层次来分析这一个月的学习。从对oo,java一无所知到逐步探索,在作业压力下学习各种知识。现在就是总结的时候了。

 

(1)基于度量来分析自己的程序结构

第一次作业:

  • 完全使用字符状态机。完全没有结构,几个方法都是截断出来的。像newNumber_t这种完全忘了是做什么用的代码。

    小总结:不熟悉java,完全没有oo思想,不会用git,对代码风格没有概念。

      强行没有使用正则表达式。对时间估计错误。

    收获:git使用,java语法。Arraylist使用。复习了状态机(…)。

      然后在讨论课上对于正则的使用有了了解,清楚基本的面向对象思路。尝试对于数据进行封装。

 

  见下方表格,ev(G),iv(G) ,v(G)都十分之高,可见代码复杂度极高,可维护性差。

  摘自百度百科--圈复杂度大说明程序代码可能质量低且难于测试和维护,根据经验,程序的可能错误和高的圈复杂度有着很大关系。

Method

ev(G)

iv(G)

v(G)

Weekk.addSign(BigInteger,char[],int)

6

1

8

Weekk.addTD(BigInteger,BigInteger)

1

2

2

Weekk.clearSign(int,char[])

1

1

4

Weekk.main(String[])

1

14

14

Weekk.newNumber_t(int,String,BigInteger)

1

3

4

Weekk.readLine()

1

1

1

Weekk.rightFormat(String)

30

29

48

    

Class

OCavg

WMC

 

hhh.Weekk

8.29

58

 
    

Project

v(G)avg

v(G)tot

 

project

11.57

81

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

第二次作业:

  小总结:基本完善较好,有了基本的面向对象的改进,代码可读性大大增强。风格和强测都全过了,互测没有被hack。

  小收获:认真听取了讨论课上同学分享的思路和意见。学习了正则表达式,hashmap的用法。在格式正确判断上有明显改进,输出时没有优化sin^2+cos^2但是其余基本最简状态。

由上图看的出,第二次作业有了初步的依赖关系,并且各类之间分工明确,逻辑、作用清晰。将多项式送到PolyArray类,先进行rightPattern判断,成功后再进入cutString切割成一项一项,将每项送到singlePoly。其中进行模式识别,传值到Derivation,在该类构建hashmap,每次导数的结果加到hashmap中,最终将hashmap导入getMap到main函数中使用printMap打印。

Method

ev(G)

iv(G)

v(G)

week.Derivation.addMap(String,BigInteger)

1

2

2

week.Derivation.cloneMap()

1

1

1

week.Derivation.der(BigInteger,BigInteger,BigInteger,BigInteger)

1

4

4

week.PolyArray.cutString(String)

1

3

3

week.PolyArray.rightPattern(String)

4

3

4

week.SinglePoly.calPoly(String)

1

14

18

week.SinglePoly.calVarTimes(String,Matcher)

1

9

10

week.Week2.main(String[])

1

4

4

week.Week2.pg(int,BigInteger,BigInteger,BigInteger)

1

9

9

week.Week2.printMap()

1

13

13

week.Week2.readLine()

2

2

2

week.Week2.select(BigInteger)

3

3

4

    

Class

OCavg

WMC

 

week.Derivation

2.33

7

 

week.PolyArray

3.5

7

 

week.SinglePoly

9.5

19

 

week.Week2

5.4

27

 
    

Package

v(G)avg

v(G)tot

 

week

6.17

74

 
    

Module

v(G)avg

v(G)tot

 

week2_Homework

6.17

74

 
    

Project

v(G)avg

v(G)tot

 

project

6.17

74

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

由左边表格可以看出来尽管代码的复杂度仍然不低,相比第一次还是有一些改进。

那我们比较关心的就是类的OCavg,看的出值高的两个类,week2和singlePoly的圈复杂度较大,而圈复杂度与分支语句的个数很有关系。尝试改进singlePoly。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

尝试了简单的重构,改变一点点正则表达式,添加xxPatx在项头的情况,删去calPoly的一些内容,可以把OCavg降到7.0。再经过对于.calVarTimes的改造,将用的while isdigit手动判断带符号数变成了不断在特定start后寻找digitPatOCavg降到6.0。再次改在calPoly,把对-号的判断移到新的方法calMinu中,可将OCavg降到4.0。

第三次作业:

  小总结:因为生病,优化不完全,但是第三次还是学会了递归调用,完成了相对复杂的任务。

  小收获:debug中构造测试树的概念,虽然这次没做好,但是对测试有更多的理解。

Method

ev(G)

iv(G)

v(G)

week.Factor.findPolyBracket(char[],String)

6

2

10

week.Factor.findTrigBracket(char[],String)

6

2

10

week.Factor.isFactor(String)

6

5

7

week.Mark.deriPolyArray(String)

1

3

3

week.Mark.getpAry()

1

1

1

week.Mark.gettAry()

1

1

1

week.Mark.replaceBracketB(String)

1

5

6

week.Mark.replaceTrigFunA(String)

6

6

6

week.Methods.reVerse(String)

1

6

8

week.PolyArray.cutStr(String)

1

3

3

week.PolyArray.judgeForm(String)

3

3

3

week.PolyArray.replaceBracket(String)

8

7

9

week.PolyArray.replaceTrigFun(String)

7

7

7

week.PolyArray.rightPattern(String)

4

3

4

week.SinglePoly.calPoly(String)

2

10

18

week.SinglePoly.deriA(String)

4

10

15

week.SinglePoly.deriB(String)

1

2

3

week.SinglePoly.deriIn(String)

6

9

15

week.SinglePoly.deriX(String)

3

5

8

week.Week3.main(String[])

1

5

5

week.Week3.readLine()

2

2

2

    

Class

OCavg

WMC

 

week.Factor

7.33

22

 

week.Mark

3.4

17

 

week.Methods

6

6

 

week.PolyArray

5.2

26

 

week.SinglePoly

8.4

42

 

week.Week3

3.5

7

 
    

Package

v(G)avg

v(G)tot

 

week

6.86

144

 
    

Module

v(G)avg

v(G)tot

 

Week3-Homework

6.86

144

 
    

Project

v(G)avg

v(G)tot

 

project

6.86

144

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

可以由图表看出,虽然也有明显的递进层次,但是没有使用接口和继承类那样清晰。

由表格,这次之前没有复杂度的概念,作业3也没有做接口和继承的优化,复杂度上不尽人意。

 

 (2)分析自己程序的bug

第一次作业:  

样例分析:

  第一次作业使用复杂度极高的字符状态机,在公测挂了几个点,在互测中也被hack了几次。而且是很明显,仔细测评一定能查出的错误。这次之后知道要花3小时左右列举各色案例,但还是没有发展出利用树来进行案例测试。

  • 公测用例1:

+       -2192*x  ^ -4723 -      1876*x^1298 + 3321 * x^ 0000 - +0000*x

错误输出:10352816*x^-4724-2435048*x^12970
正确输出:10352816*x^-4724-2435048*x^1297+0
原因:主要是打印错误,当打印系数为0项时,没有加+,只考虑了正数要打印‘+’。
  • 公测用例2:
  • 公测用例3:错误原因同用例2。
  • 公测用例4:错误原因同用例2。
·       --12345678*x^1+-87654321*x^1++19283746*x^1--47382846*x^1
+- x^ 0 --x^ +0 + 123*x^999-  +66*  x^0999-57  * x^ +999--7703*x^-39+-725* x ^ -
……
错误输出:-8642051x^998x^-40x^-91x^-57x^-51
正确输出:-8642051+0+0+0+0+0
原因:打印错误,当系数为0项时,根本不该打印该项只打+0即可。原先只是没有打印系数,却把后面的x^998等等内容打印出来。

以上公测用例错误都在方法main()中。

  • 互测用例1:
·       x^ + 1
错误原因:WF。因为使用字符状态机,为了压缩长度,将对空格和/t判断提前,使得^后不该有的符号数空白符被滤过了
  • 互测用例2:特殊字符/v/f

   错误原因:使用了trim(); 不知道trim()会去除所有空白字符。

 以上互测错误都在方法rightFormat()中。

关联分析:               

  设计结构是纯粹线性的,而bug与其的相关性也很明显,就是一个线性不断剥丝的过程,无论是结构判断还是ArrayList输出,都是这种逐步淘汰错误模式的过程。

  三个bug都是与该模式有关的,首先^后空格模式忽略就是状态机中一个状态疏忽。系数为0打印问题是个重要前提疏忽问题。而系数为0打印+也是一个个例疏忽。

  结构问题在重构时会说明,测试会在测试bug时说明。

第二次作业:略。

第三次作业:

样例分析

  公测和互测败在了同一个bug上。

  • 公测用例1:
++(sin((x+x^2))+(x)*(cos((sin(x)+x^4))))-(sin((x+1))*(x+1))
错误输出:
cos((x+x^2))*(1+2*x^1)+(1)*(cos((sin(x)+x^4)))+
(x)*(-1*sin((sin(x)+x^4))*(cos(x)*(1)+4*x^3))-1*(cos((x+1))*(1+0))*(x+1)+sin((x+1))*(1+0)
正确输出:
((cos((x+x^2))*((1)+(2*x^1)))+((1))*(cos((sin(x)+x^4)))+
(x)*(((-1*sin((sin(x)+x^4))*((cos(x)*(1))+(4*x^3))))))-1*((cos((x+1))*((1)+0))*(x+1)+sin((x+1))*(((1)+0)))
原因:当-(sin((x+1))*(x+1))出现的时候,嵌套调用和一般 表达式调用导数的区别--需要括号区分!!!!!

    一般表达式导数,每项只需要链式求导即可,最外圈无需括号

    A*B’+A’*B  -A*B’+A’*B

    嵌套需要括号!否则-号出现,会使第一项后括号反向!

关联分析

  很明显这次的结构较为紊乱。因此没有厘清所有的可能性。这就是为什么构建代码时要考虑圈复杂度,想这种圈复杂度太高,测试时需要将每条路径走多遍,就会造成bug层出,还不好检查的情况。debug超过五小时,无法找到上述bug。

同理,由分类树角度,这颗树没有一个很好的层次,枝丫太多杂乱。如果再写类似代码则需重构。

(3)分析自己发现别人程序bug所采用的策略

第一次作业:

  • 1、首先讲自己的程序应对测试的设计问题以及自行测试时的问题:
  • 有三个模式都没有测试到,^ + 1, 系数为0, 以及系数为0,且次数为1的情况。
  • 这都是常见的模式,应该在测试时予以考虑。可以利用语义集。
  • 举例:
  • 空串
  • 空格
  • +
  • *
  • 0
  • 5
  • +5
  • +-5
  •   +   -   5
  • 5*x
  • -  -5  *   x
  • -  +5 * x ^   -9
  • -  +5 * x ^   -  9
  • -  +5 * x ^   -  9  + 8
  • ……
  • 可见这个测试集是很繁琐,且一个测试用例正确,不能说明某些类型正确。这就是一个无关联度,线性结构代码的问题,bug之间松散无联系,除了强行遍历模式很难完全查出错误。
  • 2、再讲Hack别人的策略。第一次基本上是根据以上字符构造集遍历,考虑WF常见形式,这就能查出一些错误,比如空格空串,有符号数中有空格0无输出,正负号反了的错误等等。因为自己没有用正则,所以并没有着重观察正则的错误。

第二次作业:

  hack的策略主要是观察对方代码,如果与自己雷同,则着重考虑自己曾犯过或可能犯的错误。不同,则考虑自己规避的错误,而对方潜在的。

步骤主要如下:

(1)观察理解正则表达式,先找笔误。 大家的测试时间可能不充裕,这时一个正则中的笔误则可能导致一些特定样例失误。

(2)观察判断条件即思路:

  这次一个典型hack是对于“******”不显示WF的。

  该同学的思路是反向构造,即创造6个错误的pattern,如果有,则WF。这种设计就很容易找到反例,可以依症hack。

(3)还有就是题意理解点偏差纠错。这次一个很特殊的点就是+++1是正确的,可以料想有些同学仍然按作业1判断,不妨一试。

第三次作业略。

(4)Applying Creational Pattern

 

因为第三次、第二次本身就是对前面版本的重构。所以我想应用对象创建模式来对第三次作业进行重构。

 

   

原先思路没有大的问题(暂不考虑优化)。但是可读性太差了,究其原因,是singlePoly一个类担当了多个层次的问题。

4个deri可以在单设的deri类。或者就是单独设A(函数类),B(括号嵌套类),xx(单纯x)三个类,

replace可以是A,B类中的方法,而replaceA,replaceB可以是A,B的子类extends出改写的方法。

这里只是提供一个重构的思路。这样,数据被划分好了类别和层次。调用起来就清晰方便多了。  

     总结

不多说了,继续努力!

转载于:https://www.cnblogs.com/jura/p/OO_first_unit_self_conclusion_.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值