zoukankan      html  css  js  c++  java
  • 小学生四则运算--软件工程

    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("
      ");
      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("
      题目
      ");
      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
      ");
      30             }else {
      31                 System.out.println("False");
      32                 System.out.println("正确答案:"+result+"
      ");
      33             }
      34         }
      35     }
      36 }
    • 测试运行

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

    •  


       总结

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

    努力地向月光下的影子——骇客靠拢!!! 黎明之花,待时绽放
  • 相关阅读:
    C#学习第四弹之封装、继承和多态
    C#学习第三弹之给常量赋值可能引发的问题
    C#学习第二弹之C#与.NET框架
    hdu 5199 map或二分或哈希
    hdu 5195 线段树
    hdu 2545 并查集
    ACM数论模板
    C#学习第一弹之Hello World
    对字符串进行频繁拼接的话,使用StringBuffer或者StringBuilder
    String中根据,(逗号)进行分割
  • 原文地址:https://www.cnblogs.com/zzalovelyq/p/rngwudi.html
Copyright © 2011-2022 走看看