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