oo第一次总结博客

时间:2022-09-25 16:24:50

一. 多项式求导问题描述

  基本概念的声明:

  • 带符号整数 支持前导 0 的带符号整数,符号可忽略,如:+02-1619260817 等。

  • 因子

    • 变量因子
      • 幂函数
        • 一般形式 由自变量x和指数组成,指数为一个带符号整数,如:x ^ +2且,指数绝对值一律不得超过$ {10}^4 ​$
        • 省略形式 当指数为1的时候,可以采用省略形式,如:x
      • 三角函数 sin(x)cos(x),另外,本指导书范围内所有的词语“三角函数”,除非特殊说明,否则一律包含且仅包含上述两个函数
        • 一般形式 类似于幂函数,由sin(x)cos(x) 和指数组成,指数为一个带符号整数,如:sin(x) ^ +2同样的,指数绝对值一律不得超过${10}^{4}$
        • 省略形式 当指数为1的时候,可以采用省略形式,省略指数部分,如:sin(x)
    • 常数因子 包含一个带符号整数,如:233
    • 表达式因子 将在表达式的相关设定中进行详细介绍。不过,表达式因子不支持幂运算
    • 嵌套因子 本次作业将支持因子嵌套在三角函数因子里面,即一个因子作为另一个三角函数因子的自变量,例如sin(x^2)cos(sin(x)) 以及 sin(sin(cos(cos(x^2))))^2 等。但是不允许出现指数为变量的情况,指数依然只能是带符号整数,例如sin(x) ^ sin(x)是不合法的,因为指数不是自变量。也不允许幂函数的自变量为除了x之外的因子,例如1926^0817是不合法的,因为幂函数的自变量只能为x
  • 表达式 由加法和减法运算符等若干项组成,如: (-1 + x ^ 233)* sin(x^2) ^ 06 - cos(sin(x)) * 3 * sin((x))。此外,在第一项之前,可以带一个正号或者负号,如:- -1 + x ^ 233、+ -2 + x ^ 1926。此处有几点注意:空白字符 在本次作业中,空白字符包含且仅包含<space>\t。其他的除了上述会用到的字符之外,均属于非法字符。

    • 一般形式由乘法运算符连接若干任意因子组成,如:x * cos(x) * xsin(x ^ 2) * cos(sin(x)) ^ 2 * x ^ -2 等。
      • 项内因子不仅仅是同类因子
    • 特殊形式
      • 第一个因子为常数因子 1 且其后跟着乘号的时候,可以省略该常数因子或表示为正号开头的形式,如:x ^ 2 * x ^ -1、 + x ^ 2+ cos(x) * cos(x)、 sin(x) * cos(x)
      • 第一个因子为常数因子 -1 且其后跟着乘号的时候,可以表示为负号开头的形式,如:-x ^ 2、- cos(x) * sin(x)
    • 表达式因子,表达式可以作为因子,其定义为被一对小括号包裹起来的表达式,即我们允许诸如(x * cos(x)) 这种式子的出现

    • 空串不属于合法的表达式


二. 程序结构分析

1.类和方法设计综述

  • Polynomial: 控制输入输出,接受外部输入的字符串并将其传入Poly类中进行实际操作

    public class Polynomial {
    
        public static void main(String[] args) {
    Scanner input = new Scanner(System.in); if (input.hasNextLine()) {
    String str = input.nextLine();
    input.close();
    if (str.trim().isEmpty()) {
    System.out.println("WRONG FORMAT!");
    System.exit(0);
    } Poly p = new Poly(str); if (p.illegalString()) {
    System.out.println("WRONG FORMAT!");
    } else if (p.irregularString()) {
    System.out.println("WRONG FORMAT!");
    } else {
    p.output();
    }
    } else {
    System.out.println("WRONG FORMAT!");
    }
    }
    }
  • Poly

  1. 首先判断输入的字符串是否存在非法输入:非法字符、不该出现空白符的地方出现空白符。若输入的字符串符合输入规则,则将空白符号去掉。

  2. 按照表达式的构成规则将字符串分割为项,同时初始化一个Experssion类存储当前的表达式

  3. 按照项的构成规则将字符串分割为因子,同时初始化一个Factor类存储当前的项

  4. 按照因子的不同种类分别求出该因子的底数与指数,同时初始化一个Item类存储当前因子

  (若2,3,4步出现不该出现的情况则返回true,程序输入“WRONG FORMAT!”并推出)

 public boolean illegalString() {
...
} public boolean findExpression(final int begin, final int end,
final Expression curExp) {
Factor fac = new Factor();
if (judgeFactor(i, j, fac)) {
return true;
}
....
} public boolean judgeFactor(int left, int right, Factor fac) {
Item ite = new Item();
if (judgeItem(i, j, ite, leftTmp + 1)) {
return true;
}
fac.getFactors().add(ite);
....
} public boolean judgeItem(final int left, final int right, final Item ite,
final int begin) {
....
}
  • Item

    public class Item {
    private BigInteger coe;
    private BigInteger idx;
    private BigInteger curCoe;
    private BigInteger curSelfcoe;
    private int type;
    private int variableX = 0;
    private ArrayList<Expression> chain = new ArrayList<Expression>(); public String getDerivation() {
    ....
    } public String getSelf() {
    ....
    }   
  • Factor

    public class Factor {
    private int op;
    private ArrayList<Item> factors = new ArrayList<Item>(); public String getDerivation() {
    ....
    } public String getSelf() {
    ....
    }
  • Expression

    public class Expression extends Item {
    private ArrayList<Factor> expression = new ArrayList<Factor>(); public ArrayList<Factor> getExp() {
    return this.expression;
    } public String getDerivation() {
    ....
    } public String getSelf() {
    ....
    }

Expression, Factor, Item中均有getSelf和getDerivation方法,以此实现链式求导。

2.UML图展示

oo第一次总结博客

3.优缺点分析

    优点:

    1.   在最开始设计时按照多项式,项,因子层层递进的思想设计使得后续作业改动较小

    2.   按要求进行链式法则求导设计,减少了繁琐的求导过程

    3.   合理地将重复使用的函数封装为方法,减少了工作量。

    缺点:

    1.   在最后一次作业中并没有进行大规模的优化,但其实可以做一下简单的同类项合并

    2.   在处理输入时应当适当运用正则表达式,这样可以减少一部分工作量,否则就会出现在对输入进行判断时出现大量布尔表达式的情况

    3.   代码风格仍然有待提高。

    4.   在阅读指导书时要认真仔细否则会导致细节失分严重。


三. 程序问题总结- -未通过的样例及其原因分析

未通过样例

原因分析

++641310706398282959093109711020261029178921763*x^-7100862071031683371053510210321531010574509245101-+29457694746621086265146643351091037558161089*x^+29457694746621086265146643351091037558161089。。。

在阅读指导书时要仔细,注意在指导书中已经暗示会出现大数,因此应该在所有指数和系数出现的地方均用BigInteger进行记录

(((((((((((((((((((-4*cos(x)^3+3*cos(x)))))))))))))))))))))

没有考虑括号的嵌套(默认表达式由一对括号括起来)

++(sin(x))

忘记考虑多项式因子前也可以将1省略为+


四. 对象创建模式分析

总的来讲,设计模式可分为三类

  • 创建型模式:对象实例化的模式,创建型模式用于解耦对象的实例化过程。
  • 结构型模式:把类或对象结合在一起形成一个更大的结构。
  • 行为型模式:类和对象如何交互,及划分责任和算法。

借鉴博客:https://www.cnblogs.com/pony1223/p/7608955.html 中的示意图可将23种设计模式表示如下:

oo第一次总结博客

目前已经在课上接触过得模式大体有五种:

  • 单例模式:某个类只能有一个实例,提供一个全局的访问点。
  • 简单工厂:一个工厂类根据传入的参量决定创建出那一种产品类的实例。
  • 工厂方法:定义一个创建对象的接口,让子类决定实例化那个类。
  • 抽象工厂:创建相关或依赖对象的家族,而无需明确指定具体类。
  • 建造者模式:封装一个复杂对象的构建过程,并可以按步骤构造。

以第三次作业为例,可以粗略将第三次作业归为工厂模式,但实际的程序设计仍与工厂模式有一定差异。在第三次作业种,Expression,Facotr以及Item均实现了getSelf以及getDeriviation方法,但每个类中的这两种方法又存在一定差异。希望在之后的程序设计种能够更好地遵循标准设计模式


五. 心得体会

  1. 第一部分的作业相对难度不是很大,可能是因为还没有到多线程部分,但仍然提醒我要注意细节,否则因为细节失分不划算。

   2. 由于之前利用java编程较少,因此前三次作业也是对java编程语言学习的很好机会。

   3.逐渐体会到面向对象编程设计的思想和方法,希望之后在之后的作业中能继续努力。