Title

小学生四则运算--软件工程

1.

PSP

 

PSP2.1

Personal Software Process Stages

预估耗时(分钟)

实际耗时(分钟)

Planning

计划

10

10

· Estimate

· 估计这个任务需要多少时间

10

10

Development

开发

655

600

· Analysis

· 需求分析 (包括学习新技术)

30

35

· Design Spec

· 生成设计文档

30

40

· Design Review

· 设计复审 (和同事审核设计文档)

10

15

· Coding Standard

· 代码规范 (为目前的开发制定合适的规范)

5

5

· Design

· 具体设计

40

70

· Coding

· 具体编码

5h*60

8h*60

· Code Review

· 代码复审

1h*60

2h*60

· Test

· 测试(自我测试,修改代码,提交修改)

3h*60

2h*60

Reporting

报告

290

60

· Test Report

· 测试报告+博客

4h*60

3h*60

· Size Measurement

· 计算工作量

10

10

· Postmortem & Process Improvement Plan

· 事后总结, 并提出过程改进计划

40

30

合计

 

955

1785

2.项目要求

  • 能自动生成小学四则运算题目
  • 除了整数以外,还要支持真分数的四则运算
  • 解题思路

    • 了解四则运算的大概思路,即:生成四则运算式子;用户输入结果;程序检验用户输入的结果是否正确;若用户输入的结果错误,即把正确答案输入。
    • 用数组和随机函数随机生成四则运算式子;
    • 了解逆波兰式,即将中缀表示式转换成后缀表达式,以便计算机对式子进行运算;
    • 检验结果并输出;

     

    设计实现及代码说明

      1、NiBoLanShi.java

      对四则运算式子从中缀表达式转换成后缀表达式,以便计算机计算。

  •   1 package sizeyunsuan;
      2 
      3 import java.util.List;
      4 import java.math.BigDecimal;
      5 import java.util.ArrayList;
      6 import java.util.Stack;
      7 
      8 public class NiBoLanShi {
      9     public static String cal(String str) {
     10         //对表达式进行预处理,并简单验证是否是正确的表达式
     11         //存放处理后的表达式
     12         List<String> list = new ArrayList<>();
     13         char[] arr = str.toCharArray();
     14 
     15         //存放数字临时变量
     16         StringBuffer tmpStr = new StringBuffer();
     17         for (char c : arr) {
     18             //如果是数字或小数点,添加到临时变量中
     19             if (c>='0' && c<='9') {
     20                 tmpStr.append(c);
     21             }else if(c=='.') {
     22                 if(tmpStr.indexOf(".")>0) {
     23                     throw new RuntimeException("非法字符");
     24                 }
     25                 tmpStr.append(c);
     26             }
     27 
     28             //如果是加减乘除或者括号,将数字临时变量和运算符依次放入List中
     29             else if (c=='+' || c=='-' || c=='*' || c=='/' || c=='(' || c==')') {
     30                 if (tmpStr.length() > 0) {
     31                     list.add(tmpStr.toString());
     32                     tmpStr.setLength(0);
     33                 }
     34                 list.add(c + "");
     35             }
     36             else if (c==' ') {
     37                 continue;
     38             }
     39             else {
     40                 throw new RuntimeException("非法字符");
     41             }
     42         }
     43         if (tmpStr.length() > 0) {
     44             list.add(tmpStr.toString());
     45         }
     46 
     47         //初始化后缀表达式
     48         List<String> strList = new ArrayList<>();
     49 
     50         //运算过程中,使用了两次栈结构,
     51         //第一次是将中缀表达式转换成后缀表达式,第二次是计算后缀表达式的值
     52         Stack<String> stack = new Stack<>();
     53 
     54         //声明临时变量,存放栈元素
     55         String tmp;
     56 
     57         //将中缀表达式转换成后缀表达式
     58         for (String s : list) {
     59             //如果是左括号直接入栈
     60             if (s.equals("(")) {
     61                 stack.push(s);
     62             }
     63 
     64             //如果是右括号,执行出栈操作,依次添加到后缀表达式中,直到出栈元素为左括号,左括号和右括号都不添加到后缀表达式中
     65             else if (s.equals(")")) {
     66                 while (!(tmp = stack.pop()).equals("(")) {
     67                     strList.add(tmp);
     68                 }
     69             }
     70 
     71             //如果是加减乘除,弹出所遇优先级大于或等于该运算符的栈顶元素(栈中肯定没有右括号,认为左括号的优先级最低),然后将该运算符入栈
     72             else if (s.equals("*") || s.equals("/")) {
     73                 while(!stack.isEmpty()) {
     74                     //取出栈顶元素
     75                     tmp = stack.peek();//取出但不移除
     76                     if (tmp.equals("*") || tmp.equals("/")) {
     77                         stack.pop();
     78                         strList.add(tmp);
     79                     }
     80                     else {
     81                         break;
     82                     }
     83                 }
     84                 stack.push(s);
     85             }
     86             else if (s.equals("+") || s.equals("-")) {
     87                 while(!stack.isEmpty()) {
     88                     //取出栈顶元素
     89                     tmp = stack.peek();
     90                     if (!tmp.equals("(")) {
     91                         stack.pop();
     92                         strList.add(tmp);
     93                     }
     94                     else {
     95                         break;
     96                     }
     97                 }
     98                 stack.push(s);
     99             }
    100 
    101             //如果是数字,直接添加到后缀表达式中
    102             else {
    103                 strList.add(s);
    104             }
    105         }
    106 
    107         //最后依次出栈,放入后缀表达式中
    108         while (!stack.isEmpty()) {
    109             strList.add(stack.pop());
    110         }
    111 
    112         //计算后缀表达式的值
    113         Stack<BigDecimal> newStack = new Stack<>();
    114         for (String s : strList) {
    115             //若遇运算符,则从栈中退出两个元素,先退出的放到运算符的右边,后退出的放到运算符的左边
    116             //运算后的结果再进栈,直到后缀表达式遍历完毕
    117             if (s.equals("*") || s.equals("/") || s.equals("+") || s.equals("-")) {
    118                 BigDecimal b1 = newStack.pop();
    119                 BigDecimal b2 = newStack.pop();
    120                 switch (s) {
    121                 case "+":
    122                     newStack.push(b2.add(b1));
    123                     break;
    124                 case "-":
    125                     newStack.push(b2.subtract(b1));
    126                     break;
    127                 case "*":
    128                     newStack.push(b2.multiply(b1));
    129                     break;
    130                 case "/":
    131                     newStack.push(b2.divide(b1, 9, BigDecimal.ROUND_HALF_UP));
    132                     break;
    133                 }
    134             }
    135 
    136             //如果是数字,入栈
    137             else {
    138                 newStack.push(new BigDecimal(s));
    139             }
    140         }
    141 
    142         //最后,栈中仅有一个元素,就是计算结果
    143         return newStack.peek().toString();
    144     }
    145 }

    2、CreateRandom.java

      利用代码随机产生四则运算表达式。

  •  1 package sizeyunsuan;
     2 
     3 
     4 public class CreateRandom {
     5     public void create(int m, int n, String[] fuHao, String[] strArray) {
     6         String str = "";
     7 
     8         //随机生成式子
     9         for (int i = 0; i < n; i++) {
    10             str = "";
    11             int[] arr1 = new int[n];
    12             int[] arr2 = new int[n];
    13             arr2[i] = (int)(Math.random()*m+1);
    14             for(int j = 0; j < n; j++) {
    15                 int order = (int)(Math.random()*4);
    16                 arr1[j] = (int)(Math.random()*m+1);
    17                 str = str + arr1[j] + fuHao[order];
    18             }
    19             str = str + arr2[i];
    20             strArray[i] = str;
    21             System.out.println("第"+(i+1)+"题:"+str);
    22             arr1 = null;
    23             arr2 = null;
    24         }
    25         System.out.println("\n");
    26     }
    27 }

    3、Student.java

      主类,用户输入答案,检验其答案是否正确。

  •  1 package sizeyunsuan;
     2 
     3 import java.util.Scanner;
     4 
     5 
     6 
     9 public class Student {
    10 
    11     public static void main(String[] args) {
    12         CreateRandom createRandom = new CreateRandom();
    13         NiBoLanShi niBoLanShi = new NiBoLanShi();
    14         String[] fuHao = {"+","-","*","/"};
    15         Scanner input = new Scanner(System.in);
    16         System.out.println("请输入范围内的计算:");
    17         int m = input.nextInt();
    18         System.out.println("请输入要产生的题数:");
    19         int n = input.nextInt();
    20         String[] strArray = new String[n];
    21         System.out.println("\n题目\n");
    22         createShiZi.create(m, n, fuHao, strArray);
    23         for(int i = 0; i<n; i++) {
    24             String result = niBoLanShi.cal(strArray[i]);
    25             System.out.println("第"+(i+1)+"题:"+strArray[i]);
    26             System.out.print("你的答案:");
    27             String yourAnswer = input.next();
    28             if (yourAnswer.equals(result)) {
    29                 System.out.println("True\n");
    30             }else {
    31                 System.out.println("False");
    32                 System.out.println("正确答案:"+result+"\n");
    33             }
    34         }
    35     }
    36 }

     

  • 测试运行

      为了方便展示,测试以小数目为主:

  •  

     

     


     

     

     总结

       这次的用Java实现简单的四则运算,让我重拾了以前的基础知识,譬如数组,列表等等。程序看起来比较的简陋,本来是想结合墨刀的原型进行融合的,奈何能力有限,希望在后续的学习中不断充实自己,然后能完成这一目标,设计一个精美的小学生四则运算软件,有机会的话在石墨文档等互联网平台进行发布。

posted @ 2021-09-25 23:39  赖金明的大爹  阅读(310)  评论(0编辑  收藏  举报