Java实现简单四则运算


GitHub 项目地址

https://github.com/ben-qiu-zou/-


 

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

 

项目要求

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

 

解题思路

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

 

设计实现及代码说明

  1、NiBoLanShi.java

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

 

  1 package jjj.arithmetic.methods;
  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、CreateShiZi.java

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

 

 1 package jjj.arithmetic.methods;
 2 
 3 
 4 public class CreateShiZi {
 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 < (int)(Math.random()*10+1); 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 jjj.arithmetic.texts;
 2 
 3 import java.util.Scanner;
 4 
 5 
 6 import jjj.arithmetic.methods.CreateShiZi;
 7 import jjj.arithmetic.methods.NiBoLanShi;
 8 
 9 public class Student {
10 
11     public static void main(String[] args) {
12         CreateShiZi createShiZi = new CreateShiZi();
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实现简单的四则运算,让我重拾了以前的基础知识,譬如数组,列表等等。程序看起来不是很完美,运行时候或许有一些小漏洞,例如随机产生的四则运算式子中并没有加入括号;后续也并没有进行程序的性能分析,由于时间问题及个人能力有限,只能以后再继续完善了。

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM