用棧實現簡單計算器


逆波蘭式計算器

1) 輸入一個逆波蘭表達式(后綴表達式),使用棧(Stack), 計算其結果
2) 支持小括號和多位數整數,只支持對整數的計算。

思路分析:

  1. 從左至右掃描表達式,
  2. 遇到數字時,將數字壓入堆棧,
  3. 遇到運算符時,彈出棧頂的兩個數,用運算符對它們做相應的計算(次頂元素 和 棧頂元素),並將結果入棧;
  4. 重復上述過程直到表達式最右端,最后運算得出的值即為表達式的結果。

代碼實現:

1. public class Polandnotation {  
2.     public static void main(String[] args) {  
3.         String suffixExpression = "30 4 + 5 * 6 -";//逆波蘭表達式的字符串,每個字符用空格隔開  
4.         String[] s = suffixExpression.split(" ");  
5.         Stack<String> stack = new Stack<>();  
6.         for (String s1 : s) {  
7.             int res = 0;  
8.             if (Polandnotation.isNumeric(s1)) {  
9.                 stack.push(s1);  
10.             } else {  
11.                 int num2 = Integer.parseInt(stack.pop());  
12.                 int num1 = Integer.parseInt(stack.pop());  
13.                 switch (s1) {  
14.                     case "+":  
15.                         res = num1 + num2;  
16.                         break;  
17.                     case "-":  
18.                         res = num1 - num2;  
19.                         break;  
20.                     case "*":  
21.                         res = num1 * num2;  
22.                         break;  
23.                     case "/":  
24.                         res = num1 / num2;  
25.                         break;  
26.                     default:  
27.                         throw new RuntimeException("ERROR!!!!");  
28.                 }  
29.                 stack.push(String.valueOf(res));  
30.             }  
31.   
32.         }  
33.         int result = Integer.parseInt(stack.pop());//最后留在 stack 中的數據是運算結果  
34.         System.out.println(suffixExpression + " = " + result);  
35.     }  
36.   
37.     //判斷字符串是否為數字  
38.     public static boolean isNumeric(String str) {   39.         Pattern pattern = Pattern.compile("[0-9]*");   40.         return pattern.matcher(str).matches();   41.     }   42. }  

來自 <http://www.planetb.ca/projects/syntaxHighlighter/popup.php> 

 

 

 

中綴表達式計算器

注:此計算器只能進行加減乘除,且不能使用小括號

 思路分析

1、通過一個index(索引),來遍歷表達式
2、如果發現是一個數字,就直接入數棧
3、如果發現掃描到的是一個符號,就分如下情況:

1、如果發現當前符號棧為空,就直接入棧
2、如果符號棧中有操作符,就進行比較:

1、如果當前的操作符的優先級小於或等於棧中的操作符,就需要從數棧中pop出兩個數,從符號棧中pop出一個符號,進行運算,將得到的結果入數棧,再將當前的操作符(index所指)入符號棧。
2、如果當前的操作符的優先級大於棧中的操作符,就直接入符號棧。

4、當表達式掃描完畢,就順序的從數棧和符號棧中pop出相應的數和符號,並進行運算,將得到的結果入數棧
5、最后在數棧中的結果即為表達式的結果

代碼實現:

用數組實現棧來完成,棧相關操作代碼略:(arrayStack類)

1. //返回運算符的優先級,優先級是程序員來確定, 優先級使用數字表示  
2.     //數字越大,則優先級就越高.  
3.     public int priority(int oper) {  
4.         if (oper == '*' || oper == '/') {  
5.             return 1;  
6.         } else if (oper == '+' || oper == '-') {  
7.             return 0;  
8.         } else return -1;//  假定目前的表達式只有 +, - , * , /  
9.   
10.     }  
11.   
12.     //判斷是不是一個運算符  
13.     public boolean isOper(char val) {  
14.         return (val == '+' || val == '-' || val == '*' || val == '/');  
15.     }  
16.   
17.     //計算方法  
18.     public int cal(int num1, int num2, int oper) {  
19.         int res = 0;//用於存放計算結果  
20.         switch (oper) {  
21.             case '+':  
22.                 res = num1 + num2;  
23.                 break;  
24.             case '-':  
25.                 res = num2 - num1;  
26.                 break;  
27.             case '*':  
28.                 res = num1 * num2;  
29.                 break;  
30.             case '/':  
31.                 res = num2 / num1;  
32.                 break;  
33.             default:  
34.                 break;  
35.         }  
36.         return res;  
37.     }  

來自 <http://www.planetb.ca/projects/syntaxHighlighter/popup.php> 


測試類:

1. public class caculatortest {  
2.     public static void main(String[] args) {  
3.         String expression = "10 / 20 * 60";  
4.         //將expression按照空格切片,獲取每個操作符字符串和數字字符串,存在字符串數組s中  
5.         String[] s = expression.split(" ");  
6.         //創建兩個棧:數棧和符號棧  
7.         arraystack numStack = new arraystack(10);  
8.         arraystack operStack = new arraystack(10);  
9.         int index = 0;//用於掃描  
10.         int num1, num2, res;  
11.         for (String s1 : s) {  
12.             //判斷 s1 是什么,然后做相應的處理  
13.             if (operStack.isOper(s1.charAt(0))) {//如果是運算符  
14.                 if (operStack.isEmpty()) { //如果發現當前符號棧為空,就直接入棧  
15.                     operStack.push(s1.charAt(0));  
16.                 } else {//如果符號棧中有操作符,就進行比較  
17.                     //如果當前的操作符的優先級小於或等於棧中的操作符  
18.                     if (operStack.priority(s1.charAt(0)) <= operStack.priority(operStack.peek())) {  
19.                         //需要從數棧中pop出兩個數,從符號棧中pop出一個符號,進行運算,  
20.                         // 將得到的結果入數棧,  
21.                         // 再將當前的操作符(index所指)入符號棧。  
22.                         num1 = numStack.pop();  
23.                         num2 = numStack.pop();  
24.                         res = numStack.cal(num1, num2, operStack.pop());  
25.                         numStack.push(res);  
26.                         operStack.push(s1.charAt(0));  
27.                     } else {//如果當前的操作符的優先級大於棧中的操作符,就直接入符號棧。  
28.                         operStack.push(s1.charAt(0));  
29.                     }  
30.                 }  
31.             } else {//如果發現是一個數字,就直接入數棧  
32.                 int num = Integer.parseInt(s1);  
33.                 numStack.push(num);  
34.             }  
35.         }  
36.         //當表達式掃描完畢,就順序的從 數棧和符號棧中 pop 出相應的數和符號,並運行  
37.         while (true) {  
38.             //如果符號棧為空,則計算到最后的結果, 數棧中只有一個數字【結果】  
39.             if (operStack.isEmpty()) {  
40.                 break;  
41.             }  
42.             num1 = numStack.pop();  
43.             num2 = numStack.pop();  
44.             res = numStack.cal(num1, num2, operStack.pop());  
45.             numStack.push(res);  
46.         }  
47.         int result = numStack.pop();//將數棧的最后數,pop出,就是結果  
48.         System.out.printf("表達式 %s = %d", expression, result);  
49.     }  
50. }  

來自 <http://www.planetb.ca/projects/syntaxHighlighter/popup.php> 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM