zoukankan      html  css  js  c++  java
  • 面向对象第一单元总结

      第一单元的主要目标是了解面向对象的概念、认识对象的关键特性、了解并逐渐掌握层次化抽象和设计方法。单元内三次作业都围绕着函数求导这一主题,循序渐进地培养编写基本的面向对象程序的能力。

    一、第一次作业:幂函数求导

      第一次作业的要求是对仅包含常数和幂函数的多项式进行求导。自然的想法是,构造一个“项”对象,它包含系数和指数两个变量,多项式便是这样的项的集合。读入一个项后检查是否能与现有项合并化简,之后依次按公式求导,输出时优先输出系数为正的项。比较复杂的部分是输入环节,由于规则繁多,我总结出一个状态机并据此实现了InputReader类:

      度量分析:

        方法:

    InputReader.InputReader() 1.0 1.0 1.0
    InputReader.isNumber(char) 1.0 1.0 2.0
    InputReader.isSign(char) 1.0 1.0 2.0
    InputReader.isSpace(char) 1.0 1.0 2.0
    InputReader.phase0(ArrayList) 5.0 6.0 8.0
    InputReader.phase1(ArrayList) 5.0 5.0 8.0
    InputReader.phase2(ArrayList) 3.0 7.0 8.0
    InputReader.phase3(ArrayList) 2.0 3.0 5.0
    InputReader.phase4(ArrayList) 3.0 5.0 6.0
    InputReader.phase5(ArrayList) 4.0 4.0 6.0
    InputReader.phase6(ArrayList) 3.0 2.0 4.0
    InputReader.phase7(ArrayList) 2.0 6.0 7.0
    InputReader.phase8(ArrayList) 2.0 2.0 7.0
    InputReader.readItems(ArrayList) 5.0 6.0 7.0
    Item.add(Item) 1.0 1.0 1.0
    Item.calcNewCoeff() 1.0 1.0 1.0
    Item.derive(boolean) 1.0 9.0 9.0
    Item.getCoefficient() 1.0 1.0 1.0
    Item.getIndex() 1.0 1.0 1.0
    Item.getNewCoefficient() 1.0 1.0 1.0
    Item.isAlive() 1.0 1.0 1.0
    Item.Item(String,String) 1.0 1.0 1.0
    PolynomialDerivation.combineItems() 1.0 11.0 11.0
    PolynomialDerivation.main(String[]) 6.0 6.0 7.0

        类:

    InputReader 4.0 56.0
    Item 1.875 15.0
    PolynomialDerivation 7.0 14.0
    Total   85.0
    Average 3.5416666666666665 28.333333333333332

        UML类图:

        这次作业由于要求简单,实现的结构也较为简单,不需要继承、接口等。主要可优化的部分在于InputReader类,最好改成更加可读的实现方式。

      BUG:

        主要BUG来源于对输入数据规范的理解不清晰。例如在何种情况下允许正负号与系数之间出现空格,对空行和无输入的处理等。在编写过程中发现BUG的主要方法是根据自己认为的边界值及易错点构建测试样例,与同学交换测试样例大量测试。

    二、第二次作业:三角函数以及函数相乘

      第二次作业的规则引入了sin(x)和cos(x)函数,并且允许一项内出现同类或异类函数相乘。我第一次作业的设计不能表示这样的结构,需要在项(Item)之下引入新的因子(Factor)类。将InputReader中的部分状态机删除并简化为readFunction()、readItem()等函数。读入sin(x)和cos(x)时利用规则投机取巧采用了字符串间隔匹配,导致第三次作业该部分需要重写。有考虑到基于sin(x)^2+cos(x)^2=1的优化,但实现过程中出现了bug,最终舍弃。

      度量分析:

        方法:

    Factor.add(Factor) 1.0 1.0 1.0
    Factor.derive() 3.0 2.0 6.0
    Factor.Factor(String,String) 2.0 2.0 5.0
    Factor.getIndex() 1.0 1.0 1.0
    Factor.getType() 1.0 1.0 1.0
    Factor.getValue() 1.0 1.0 1.0
    Factor.isConst() 1.0 2.0 2.0
    Factor.isNegativeOne() 1.0 2.0 2.0
    Factor.isOne() 2.0 2.0 2.0
    Factor.isPositive() 1.0 1.0 1.0
    Factor.isZero() 1.0 2.0 2.0
    Factor.setIndex(BigInteger) 1.0 1.0 1.0
    Factor.sub(Factor) 1.0 1.0 1.0
    Factor.times(Factor) 1.0 2.0 2.0
    Factor.toString() 4.0 4.0 4.0
    InputReader.filterSpaces() 1.0 2.0 3.0
    InputReader.InputReader() 1.0 1.0 1.0
    InputReader.intervalMatching(String) 3.0 3.0 4.0
    InputReader.isFunction(char) 1.0 1.0 3.0
    InputReader.isNumber(char) 1.0 1.0 2.0
    InputReader.isSign(char) 1.0 1.0 2.0
    InputReader.isSpace(char) 1.0 1.0 2.0
    InputReader.newItem(Polynomial) 1.0 2.0 2.0
    InputReader.phase0(Polynomial) 4.0 6.0 6.0
    InputReader.phase1(Polynomial) 4.0 6.0 6.0
    InputReader.phase2(Polynomial) 3.0 4.0 4.0
    InputReader.phase3(Polynomial) 2.0 6.0 6.0
    InputReader.phase4(Polynomial) 4.0 5.0 5.0
    InputReader.phase5(Polynomial) 8.0 2.0 9.0
    InputReader.readFunction(Polynomial,String) 5.0 9.0 9.0
    InputReader.readIndex() 5.0 4.0 8.0
    InputReader.readPolynomial(Polynomial) 5.0 5.0 6.0
    InputReader.seriesMatching(String) 3.0 3.0 4.0
    Item.add(Item) 1.0 1.0 1.0
    Item.combine(Item) 2.0 2.0 3.0
    Item.derive() 2.0 6.0 7.0
    Item.getFactors() 1.0 1.0 1.0
    Item.isPositive() 1.0 1.0 1.0
    Item.isSameType(Item) 3.0 2.0 3.0
    Item.isZero() 1.0 1.0 1.0
    Item.Item() 1.0 1.0 1.0
    Item.sub(Item) 1.0 1.0 1.0
    Item.times(Factor) 1.0 1.0 1.0
    Item.times(Item) 1.0 2.0 2.0
    Item.times(String) 1.0 1.0 1.0
    Item.toString() 2.0 7.0 7.0
    Polynomial.add(Item) 3.0 5.0 5.0
    Polynomial.add(Polynomial) 1.0 2.0 2.0
    Polynomial.combine() 2.0 5.0 6.0
    Polynomial.derive() 1.0 2.0 2.0
    Polynomial.getItems() 1.0 1.0 1.0
    Polynomial.isEmpty() 1.0 1.0 1.0
    Polynomial.Polynomial() 1.0 1.0 1.0
    Polynomial.toString() 2.0 5.0 7.0
    PolynomialDerivation.main(String[]) 1.0 2.0 2.0

        类:

    Factor 1.9333333333333333 29.0
    InputReader 3.388888888888889 61.0
    Item 2.076923076923077 27.0
    Polynomial 3.0 24.0
    PolynomialDerivation 2.0 2.0
    Total   143.0
    Average 2.6 28.6

        UML类图:

        为方便合并同类项,对Factor以及Item类定义了基本运算,但其实add()与sub()是重复的。虽然没有继承自己定义的父类,但第一次重载了toString()方法,使得输出多项式更加简单,也更加便于输出前的检查。

      BUG:

        在实现cos(x)^2+sin(x)^2=1优化时出现了两个未能通过的中测数据点。后来经过分析,初步认定是化简后合并同类项时系数计算错误导致的。另一方面,加入因子类使得项的合并需要经过大量搜索,前期采用ArrayList存储因子会使得时间复杂度提升一个量级,因此改用HashMap实现。但这又是一个仅对第二次作业适用的手段(因为所有的sin和cos函数都相同)。

    三、第三次作业:函数嵌套

      第三次作业不再限制函数的自变量为x,这意味着三角函数和幂函数可以不断递归嵌套。我采用的方法是将幂函数、三角函数的自变量定义为多项式(多项式为项的和,项为系数和函数的积),再定义一个没有因子的x函数作为递归结构的终点。与递归构建多项式对应,在读入数据是采用了完全可解释的递归读入方法。第三次作业由于输入复杂,优化算法时间复杂度高风险高而收益低,因此只做了合并同类项程度的优化。

      度量分析:

        方法:

    ConstFunc.ConstFunc(String) 1.0 1.0 1.0
    ConstFunc.derive() 1.0 1.0 1.0
    ConstFunc.getIndex() 1.0 1.0 1.0
    ConstFunc.getType() 1.0 1.0 1.0
    ConstFunc.getVar() 1.0 1.0 1.0
    ConstFunc.isSameTypeWith(Func) 1.0 1.0 1.0
    ConstFunc.isSameWith(Func) 1.0 2.0 2.0
    ConstFunc.times(Func) 1.0 1.0 1.0
    CosFunc.CosFunc(Polynomial,String) 1.0 1.0 1.0
    CosFunc.derive() 1.0 2.0 2.0
    CosFunc.getIndex() 1.0 1.0 1.0
    CosFunc.getType() 1.0 1.0 1.0
    CosFunc.getVar() 1.0 1.0 1.0
    CosFunc.isSameTypeWith(Func) 1.0 2.0 2.0
    CosFunc.isSameWith(Func) 1.0 2.0 2.0
    CosFunc.times(Func) 1.0 1.0 1.0
    CosFunc.toString() 2.0 3.0 3.0
    InputReader.atEnd() 1.0 2.0 2.0
    InputReader.filterSpaces() 1.0 2.0 3.0
    InputReader.InputReader() 1.0 2.0 2.0
    InputReader.isNumber(char) 1.0 1.0 2.0
    InputReader.isSign(char) 1.0 1.0 2.0
    InputReader.isSpace(char) 1.0 1.0 2.0
    InputReader.newConstPoly(String) 1.0 1.0 1.0
    InputReader.newFuncPoly(Func) 2.0 1.0 2.0
    InputReader.readConstFunc() 2.0 1.0 2.0
    InputReader.readCosFunc() 4.0 1.0 4.0
    InputReader.readFunc() 7.0 7.0 8.0
    InputReader.readIndex() 4.0 3.0 5.0
    InputReader.readInSin() 9.0 9.0 12.0
    InputReader.readItem() 5.0 8.0 11.0
    InputReader.readPolynomial(Polynomial,boolean) 7.0 3.0 9.0
    InputReader.readPowerFunc() 2.0 1.0 2.0
    InputReader.readSignedInt() 5.0 4.0 8.0
    InputReader.readSinFunc() 4.0 1.0 4.0
    InputReader.readXFunc() 2.0 1.0 2.0
    InputReader.seriesMatching(String) 3.0 3.0 4.0
    Item.add(Item) 1.0 1.0 1.0
    Item.derive() 2.0 4.0 5.0
    Item.filterOne() 1.0 3.0 3.0
    Item.getCoefficient() 1.0 1.0 1.0
    Item.getFuncArray() 1.0 1.0 1.0
    Item.isOne() 1.0 2.0 2.0
    Item.isPositive() 1.0 1.0 1.0
    Item.isSameTypeWith(Item) 6.0 3.0 6.0
    Item.isSameWith(Item) 1.0 2.0 2.0
    Item.isZero() 4.0 3.0 5.0
    Item.Item() 1.0 1.0 1.0
    Item.processFunc(int) 2.0 3.0 3.0
    Item.times(Func) 5.0 6.0 7.0
    Item.times(Item) 1.0 2.0 2.0
    Item.times(String) 1.0 1.0 1.0
    Item.toString() 1.0 6.0 7.0
    Polynomial.add(Item) 3.0 4.0 4.0
    Polynomial.add(Polynomial) 1.0 2.0 2.0
    Polynomial.clone() 1.0 2.0 2.0
    Polynomial.derive() 1.0 2.0 2.0
    Polynomial.filterZero() 1.0 3.0 3.0
    Polynomial.getItems() 1.0 1.0 1.0
    Polynomial.isOne() 1.0 2.0 2.0
    Polynomial.isSameWith(Polynomial) 6.0 3.0 6.0
    Polynomial.isZero() 4.0 2.0 4.0
    Polynomial.multiFactor() 1.0 3.0 3.0
    Polynomial.multiItem() 1.0 1.0 1.0
    Polynomial.Polynomial() 1.0 1.0 1.0
    Polynomial.times(Item) 1.0 2.0 2.0
    Polynomial.times(Polynomial) 1.0 2.0 2.0
    Polynomial.toString() 2.0 5.0 7.0
    PolynomialDerivation.main(String[]) 1.0 2.0 2.0
    PowerFunc.derive() 1.0 2.0 2.0
    PowerFunc.getIndex() 1.0 1.0 1.0
    PowerFunc.getType() 1.0 1.0 1.0
    PowerFunc.getVar() 1.0 1.0 1.0
    PowerFunc.isSameTypeWith(Func) 1.0 2.0 2.0
    PowerFunc.isSameWith(Func) 1.0 2.0 2.0
    PowerFunc.PowerFunc(Polynomial,String) 1.0 1.0 1.0
    PowerFunc.times(Func) 1.0 1.0 1.0
    PowerFunc.toString() 1.0 2.0 2.0
    SinFunc.derive() 1.0 2.0 2.0
    SinFunc.getIndex() 1.0 1.0 1.0
    SinFunc.getType() 1.0 1.0 1.0
    SinFunc.getVar() 1.0 1.0 1.0
    SinFunc.isSameTypeWith(Func) 1.0 2.0 2.0
    SinFunc.isSameWith(Func) 1.0 2.0 2.0
    SinFunc.SinFunc(Polynomial,String) 1.0 1.0 1.0
    SinFunc.times(Func) 1.0 1.0 1.0
    SinFunc.toString() 2.0 3.0 3.0
    XFunc.derive() 1.0 2.0 2.0
    XFunc.getIndex() 1.0 1.0 1.0
    XFunc.getType() 1.0 1.0 1.0
    XFunc.getVar() 1.0 1.0 1.0
    XFunc.isSameTypeWith(Func) 1.0 1.0 1.0
    XFunc.isSameWith(Func) 1.0 2.0 2.0
    XFunc.times(Func) 1.0 1.0 1.0
    XFunc.toString() 2.0 2.0 2.0
    XFunc.XFunc(String) 1.0 1.0 1.0

        类:

     

    ConstFunc 1.0 8.0
    CosFunc 1.3333333333333333 12.0
    InputReader 3.5 70.0
    Item 2.5625 41.0
    Polynomial 2.533333333333333 38.0
    PolynomialDerivation 2.0 2.0
    PowerFunc 1.2222222222222223 11.0
    SinFunc 1.3333333333333333 12.0
    XFunc 1.2222222222222223 11.0
    Total   205.0
    Average 2.1354166666666665 22.77777777777778

        UML类图:

        定义了Func接口,由于前期对题目理解的问题,多定义了一个PowerFunc用于处理装载(x+2)^2的函数。由于实际不会出现,故其指数固定为1,用作多项式容器。常函数仅为便于读入而存在,因为对Item(项)类的定义中有单独的系数代表所有常数的乘积,而在读入时一并视为因子读入。这是设计得不够优美的地方。多项式类函数过多有些冗杂,其中有一些为优化而存在的函数最终并未调用。

      BUG:

        在输出时省略了部分括号导致出现BUG。比如cos(x+2)是非法输出,应为cos((x+2))。这与我在设计程序时将多项式直接作为三角函数的自变量不无关系,但可以通过在输出时添加一些判断解决。

    四、Applying Creational Pattern

      对于存储多项式、项和函数的类,都定义了基本运算、求导和输出函数,因此可看做使用了工厂模式。在前两次作业中尝试了简单工厂模式,第三次作业部分使用了抽象工厂模式。简单工厂模式能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。明确区分了各自的职责和权力,有利于整个程序结构的优化。但在类的数量增多时,难以理清大局。这三次作业是不断重构的过程,已经可以体现一部分对创建模式的改进。若对第三次作业进一步改进,可以考虑的方向有:拆分InputReader,将Function的加、乘方法写进父类等。

  • 相关阅读:
    aop 注解 开启spring自带的事务
    springmvc异常统一处理
    ZeroMQ接口函数之 :zmq_ctx_get
    ZeroMQ接口函数之 :zmq_ctx_destroy
    ZeroMQ接口函数之 :zmq_connect
    ZeroMQ接口函数之 :zmq_close
    ZeroMQ接口函数之 :zmq_bind
    ZeroMQ接口函数之 :zmq
    nmap的script参数列表
    一个不错的安卓下ssh客户端
  • 原文地址:https://www.cnblogs.com/starmind/p/10611187.html
Copyright © 2011-2022 走看看