MathExam V2.0

Posted li-zhen-cn

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MathExam V2.0相关的知识,希望对你有一定的参考价值。

# 隔壁村小学的小朋友都羡慕哭了2.0版

一、预估与实际

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 15 20
? Estimate ? 估计这个任务需要多少时间 800 1000
Development 开发 600 600
? Analysis ? 需求分析 (包括学习新技术) 30 60
? Design Spec ? 生成设计文档 20 30
? Design Review ? 设计复审 10 30
? Coding Standard ? 代码规范 (为目前的开发制定合适的规范) 10 10
? Design ? 具体设计 30 40
? Coding ? 具体编码 400 500
? Code Review ? 代码复审 20 15
? Test ? 测试(自我测试,修改代码,提交修改) 60 45
Reporting 报告 60 60
? Test Repor ? 测试报告 30 30
? Size Measurement ? 计算工作量 20 15
? Postmortem & Process Improvement Plan ? 事后总结, 并提出过程改进计划 20 30
合计 1000

二、需求分析

我通过网上查阅和询问担任担任小学老师的姑姑了解到,小学三年级数学四则混合运算有如下的几个特点:

  • 会1000以内加减乘除法(通过查阅教材发现:要求掌握两位数乘除两位数)
  • 运算符在2~4个
  • 可以加括号
  • 减法运算的结果不能有负数
  • 除法运算除数不能为0,不能有余数

三、设计

1. 设计思路

说明你如何设计这个程序

  • 首先,我先分析了三年级题目的难度,确认了生成随机两位数的大小
  • 然后思考如何生成无括号的四则运算
  • 最后将括号加入,计算

2. 实现方案

写出具体实现的步骤

  • 分析了三年级题目的难度,确认了生成随机数的大小
  • 然后思考如何生成无括号的四则运算

四、编码

  • 首先我要解决的问题是,如何运算无括号的四则运算式
  • 我同样只用优先级的方法,写出Operation函数,先将* / 这种优先级较高的运算符运算,然后将运算过的符号与数值变为null,然后调用去除null的函数,将null移动至数组最后一位
  • 然后剩下的只有加减法,依次运算既可得出结果
  • 然后我们需要考虑括号因素,我打算先随机出括号的位置,与括号中的符号的数量,然后将括号内的数值与符号存入另一个数组,然后经过Operation函数运算,得出answer,然后将这些运算过的数值符号赋值null,调用removenull函数去除null
  • 然后我将已经去除括号的运算式再次使用Operation函数运算出结果

1. 调试日志

  • 在数组中存入数据,调用时发生越界,空指针

2. 关键代码

public static double Operation(String[] OpeMarkStrNumber, String[] OpeNumber) {          //首先遍历一遍存储运算符的数组,寻找到* /这种优先级较高的运算符,运算出结果,然后将运算过的符号与数值改为null,然后使用去除null的函数,去掉null数据
    while(true) {
        int PMAmount = 0;
        for(int i = 0; i < OpeMarkStrNumber.length-1; i++) {
            
            if(OpeMarkStrNumber[i] == "*") {
                
                double ans = Double.parseDouble(OpeNumber[i]) * Double.parseDouble(OpeNumber[i+1]);
                
                OpeNumber[i] = String.valueOf(ans);
                OpeNumber[i+1] = null;
                OpeMarkStrNumber[i] = null;
                OpeNumber = RemoveNull(OpeNumber);
                OpeMarkStrNumber = RemoveNull(OpeMarkStrNumber);
                
                PMAmount++;
                break;
                
            }else if(OpeMarkStrNumber[i] == "/") {
                
                double ans = Double.parseDouble(OpeNumber[i]) / Double.parseDouble(OpeNumber[i+1]);
                OpeNumber[i] = String.valueOf(ans);
                OpeNumber[i+1] = null;
                OpeMarkStrNumber[i] = null;
                OpeNumber = RemoveNull(OpeNumber);
                OpeMarkStrNumber = RemoveNull(OpeMarkStrNumber);
                PMAmount++;
                break;
            }
        }
        
        if(PMAmount == 0) {
            break;
        }
    }
    return PlusMinus(OpeMarkStrNumber, OpeNumber);
}

public static double PlusMinus(String[] OpeMarkStrNumber, String[] OpeNumber) {       //当乘除法被消除完之后,可以依次运算加减法,最终得出结果

    int PMmarkNo = 0;
    double ans = Double.parseDouble(OpeNumber[0]) ;
    while(true) {
        if(OpeMarkStrNumber[PMmarkNo] == "+") {
            ans = ans + Double.parseDouble(OpeNumber[PMmarkNo+1]);
            PMmarkNo++;
        }else if(OpeMarkStrNumber[PMmarkNo] == "-"){
            ans = ans - Double.parseDouble(OpeNumber[PMmarkNo+1]);
            PMmarkNo++;
        }else if(OpeMarkStrNumber[PMmarkNo] == null){
            return ans;
        }
    }
}


public static String[] RemoveNull(String[] target) {     //去除null 函数,将数组中的null移动至数组后面
    for(int i = 0; i < target.length; i++) {
        if(target[i] == null) {
            for(int j = i; j < target.length; j++) {
                if(j != target.length-1) {
                    target[j] = target[j+1];
                }else {
                    target[j] = null;
                }
            }
        }
    }
    return target;
}

```

3. 代码规范

请给出本次实验使用的代码规范:

  • 第一条:不允许任何未经预先定义的常量直接出现在代码中。
  • 第二条:大括号的使用约定。如果是大括号内为空,则简介地写成{}即可,不需要换行;如果是非空代码块则:左大括号前不换行。左大括号后换行。右大括号前换行。右大括号后还有 else 等代码则不换行;表示终止的右大括号后必须换行。
  • 第三条:左小括号和字符之间不出现空格;同样的,有小括号和字符之间也不出现空格。
  • 第四条:在 if/else/for/while/do 语句中必须使用大括号。
  • 第五条:任何二目、三木运算符的左右两边都需要加一个空格。
  • 第六条:单行字符数限制不超过120个,超出需要换行,换行时遵循如下原则:第二行相对第一行缩进 4 个空格,从第三行开始,不再继续缩进,参考示例。运算符与下文一起换行。方法调用的点符号与下文一起换行。方法调用时,多个参数,需要换行时,在逗号后进行。

并人工检查代码是否符合规范

五、测试

  • 输入5 3

  • 输出
  • (1)10*(17-7)=
  • (2)18*9/3=
  • (3)16*3-2-10=
  • (4)20/(16-15)=
  • (5)20-16-18/9=
  • ------------------标准答案------------------
  • (1)10*(17-7)=100.0
  • (2)18*9/3=54.0
  • (3)16*3-2-10=36.0
  • (4)20/(16-15)=20.0
  • (5)20-16-18/9=2.0

    六、总结

  • 从刚看到题目时的不知所措,第一想法就是“我不会”,但是又想到这是一次结对作业,正所谓三个臭皮匠赛过诸葛亮,两个“臭皮匠"来解决这个三年级四则运算应该也绰绰有余了吧,通过相互间的讨论,解决了一些数组的越界,以及空指针的错误,节约了一些修改BUG的时间,对于不会的东西勤百度,这是解决问题的途径之一。

技术分享图片

以上是关于MathExam V2.0的主要内容,如果未能解决你的问题,请参考以下文章

软件工程实例操作---MathExam

MathExam

MathExam

MathExam

MathExam

MathExam小学一二年级计算题生成器V1.0