BUAA_OO_UNIT1总结

张子豪-22371011 学生 2024-03-21 18:06:55

1.最终架构

1.1预处理部分(Preprocessor)

1.1.1空白符处理

利用正则表达式匹配空白符,利用replaceAll()方法删除。

1.1.2删除连续+-号

可以利用若干个连续+-分割表达式成若干个子字符串,判断连续正负号的最终性质为+还是为-,分别用单个正负号将子字符串连接在一起。

1.1.3储存自定义函数

通过Hashmap,储存函数名与函数表达式的对应,储存函数名和形参的键值对。

private static HashMap<String, String> nameToFunc = new HashMap<>();
    
private static HashMap<String, ArrayList<String>> nameToPara = new HashMap<>();

 

1.2词法分析

1.1.1Token

public enum Type {
        ADD, SUB, MUL, LPAREN, RPAREN, NUM, POW, X, EXP,F,G,H,CM,DX
    }

分析表达式包含的所有基本类型。

1.1.2Lexer

private ArrayList<Token> tokens = new ArrayList<Token>();

public Lexer(String input) {
        for (int pos = 0; pos < input.length();) {
            if (input.charAt(pos) == '(' || input.charAt(pos) == ')') {
                lexerParen(input.charAt(pos));
                pos++;
            } else if (input.charAt(pos) == '+' || input.charAt(pos) == '-') {
                lexerOp(input.charAt(pos));
                pos++;
             ...
        }
}

用于收集表达式的所有信息,便于下一步分析。

1.1.3Parser

1.1.3.1分析总体思路

使用递归下降法,parserExpr()分析表达式,保存项之间的符号并对每一项使用方法parserTerm(),分析项中的每一个因子parserFactor()。

parserExpr()可以调用parserTerm()
parserTerm()可以调用parserFactor()
parserFactor()分析幂函数因子、数字因子、自定义函数因子、求导因子、表达式因子,返回值为Factor类,其中可以递归调用parserExpr()

 

1.1.3.2替换自定义函数(hw2)

在parser过程中,通过调用parserFuncFctor(),传入实参,替换形参,返回一个字符串,再通过调用parserExpr(),返回表达式因子,这样就完成了自定义函数的替换。

1.1.3.3求导(hw3)

在parser过程中,通过parserDxFactor(),继续parserExpr(),得到一个表达式,再通过多项式求导方法得到一个Poly,再通过Poly类的toExpr(),这样就有了求导后的表达式因子。

 

1.3多项式展开与输出

1.3.1Mono类

private BigInteger exp;

private BigInteger coef;

private Poly expPoly = new Poly();

private int expPow = 0;

private boolean containExp = false;

是多项式的基本单位:a*x^{b}*(exp())^{c}

包含toString()方法。

 

1.3.2Poly类

private ArrayList<Mono> monoArrayList = new ArrayList<Mono>();

    public String toString() {
        StringBuilder sb = new StringBuilder();
        if (this.getMonoArrayList().size() == 0) {
            return "0";
        }
        sb.append(this.getMonoArrayList().get(0).toString());
        for (int i = 0; i < this.getMonoArrayList().size() - 1; i++) {
            if (this.getMonoArrayList().get(i + 1).getCoef() == BigInteger.ZERO) {
                continue;
            }
            sb.append("+");
            sb.append(this.getMonoArrayList().get(i + 1).toString());
        }
        return sb.toString();
    }

包含三个运算方法addPoly()、multPoly()、powPoly()来展开,通过derive()进行对Poly的求导。

1.3.3toPoly()方法

通过上文的词法分析可以得到表达式的所有信息,以expr保存。经过Expr、Term、Factor类的toPoly()方法来递归获得Poly。

这实际是展开括号的过程。

1.3.3toString()方法

用于输出。

 

2.迭代过程

并无重构

2.1hw1

在第一次作业中,显然选择使用课程中的递归下降来解构表达式,而在面对去括号的思考中,我认识到递归的展开或者递归的展开成多项式可以解决嵌套括号,于是打好了地基,这也是三次作业没有重构的根本原因。

2.2hw2

这一次作业难度较大,因为多项式的基本结构改变了,我先实现了exp信息的储存,改变了合并同类项的条件。

面对自定义函数,在词法分析时来替换func成表达式因子。

增加了Exp类、FuncFactor类

2.3hw3

第三次作业只需同理其他因子,为得到表达式和Poly这个目标来努力。

2.4可扩展性

由于项目含有多项式的确立和各种用来解构表达式的递归函数方法,代码在新增需求时,只需以下步骤:

(1)分析单项式是否有变化,调整单项式性质

(2)分析多项式运算的变化,调整addPoly()、multPoly()、powPoly()、derive()。

(3)分析新增内容是否改变toPoly()。

(4)在递归下降中插入新增需求。

(5)分析输出toString()。

 

3.bug分析和策略

3.1hw1

bug主要是在Poly运算前,没有合并同类项,导致计算错误,或者Poly没有合并。

而且没有考虑*后为负数,即面对*-会出现bug

3.2hw2

3.2.1溢出

0
(((((((((((x^8)^8)^8)^8)^8)^8)^8)^8)^8)^8)^8)^8

没有考虑幂的范围超出Integer

3.2.2TLE

在多项式运算过程中会产生很多COEF为0的项,对这些无用项运算时,会浪费很多时间,并且产生更多无用的0项。所以在运算前删除为0的mono,可以解决TLE问题。

3.3hw3

 

4.分析他人程序

(1)思考边界情况,如0^0、次幂的范围。

(2)分析易错的情况如exp((-x)),检查他人代码是否含有特判。

(3)生成简单的测试用例后,检验他人代码是否正确输出,来确定他人代码没有特别大问题。

 

5.优化

5.1性能

及时删除没用的0项。

5.2toString()优化

(1)系数COEF为0则不输出+、-和接下来0*x^a*exp...

(2)coef为1或-1时,不输出1或-1

(3)x^1时只输出x,exp同理

(4)在合并同类项的时候,exp因子判等后,会提出两个exp的次幂在合并前的公因数,大多情况下,是可以减少长度的。

5.3代码可读性

将预处理和自定义函数等单独写静态方法,使得结构性增强。

 

6.心得体会

第一次作业是最难的,0到1最难的就是开始。

面向对象项目的完成,首先需要有清晰的实现框架,先搭建好信息储存和信息分析过程,然后,搭建好所构成的类,通过分析各自类的作用和属性来选择类之间继承、接口等关系,通过方法的调用来实现处理信息的过程,最后完成信息处理结果的优化后的输出。

而整个信息处理过程,最重要的是开始,好的架构地基可以减少需要重构的情况。

经过OO的一单元学习,深刻地认识到了面向对象的魅力,近千行的代码更让我的能力逐渐提升。

 

7.未来方向

第一单元的作业已经是很完美的课设了,但是第一次作业对于没有学过OOPRE的同学很不友好,建议第一次作业实现嵌套括号,这样可以让学生优先考虑递归的使用,而不是走其他不易迭代的弯路。

 

 

 

...全文
47 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

301

社区成员

发帖
与我相关
我的任务
社区描述
2023年北航面向对象设计与构造
学习 高校
社区管理员
  • YannaZhang
  • CajZella
  • C_ecelia
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧