表達式計算 java 後綴表達式

題目:git

問題描述
  輸入一個只包含加減乖除和括號的合法表達式,求表達式的值。其中除表示整除。
輸入格式
  輸入一行,包含一個表達式。
輸出格式
  輸出這個表達式的值。
樣例輸入
1-2+3*(4-5)
樣例輸出
-4
數據規模和約定
  表達式長度不超過100,表達式運算合法且運算過程都在int內進行。
 
 

初看此題,從人的直觀角度來講很簡單,先遍歷括號內的運算完再從新遍歷,可是很麻煩。spa

回憶起了後綴表達式的知識code

 

中綴表達式轉後綴表達式的方法:
1.遇到操做數:直接輸出(添加到後綴表達式中)
2.棧爲空時,遇到運算符,直接入棧
3.遇到左括號:將其入棧
4.遇到右括號:執行出棧操做,並將出棧的元素輸出,直到彈出棧的是左括號,左括號不輸出。
5.遇到其餘運算符:加減乘除:彈出全部優先級大於或者等於該運算符的棧頂元素,而後將該運算符入棧
6.最終將棧中的元素依次出棧,輸出。blog

後綴表達式的計算機求值:
與前綴表達式相似,只是順序是從左至右:
從左至右掃描表達式,遇到數字時,將數字壓入堆棧,遇到運算符時,彈出棧頂的兩個數,用運算符對它們作相應的計算(次頂元素 op 棧頂元素),並將結果入棧;重複上述過程直到表達式最右端,最後運算得出的值即爲表達式的結果。
例如後綴表達式「3 4 + 5 × 6 -」:
(1) 從左至右掃描,將3和4壓入堆棧;
(2) 遇到+運算符,所以彈出4和3(4爲棧頂元素,3爲次頂元素,注意與前綴表達式作比較),計算出3+4的值,得7,再將7入棧;
(3) 將5入棧;
(4) 接下來是×運算符,所以彈出5和7,計算出7×5=35,將35入棧;
(5) 將6入棧;
(6) 最後是-運算符,計算出35-6的值,即29,由此得出最終結果。string

 

一開始,我先把中綴表達式轉換爲後綴表達式,再對後綴表達式求值。it

有一個很大的問題,數字的保存,轉化爲後綴表達式時保存爲char字符,對於大於9的數字保存很麻煩。class

後來想了想,能夠直接借用後綴表達式的計算方法。遍歷

代碼以下方法

 1 public class Main {
 2     public static void main(String[] args) {
 3         // TODO Auto-generated method stub
 4         Scanner scanner = new Scanner(System.in);
 5         Stack<Integer> nums = new Stack<Integer>(); // 保存數字
 6         Stack<Character> opes = new Stack<Character>(); // 保存操做符
 7         String string = scanner.nextLine();
 8         int n = 0; // 保存每個數字
 9         char[] cs = string.toCharArray();
10         for (int i = 0; i < cs.length; i++) {
11             char temp = cs[i];
12             if (Character.isDigit(cs[i])) {
13                 n = 10 * n + Integer.parseInt(String.valueOf(cs[i])); // 大於10的數字保存
14             } else {
15                 if (n != 0) {
16                     nums.push(n);
17                     n = 0;
18                 }
19                 if (temp == '(') {
20                     opes.push(temp);
21                 } else if (temp == ')') {
22                     while (opes.peek() != '(') { // 括號裏面運算完
23                         int t = cal(nums.pop(), nums.pop(), opes.pop());
24                         nums.push(t);
25                     }
26                     opes.pop();
27                 } else if (isType(temp) > 0) {
28                     if (opes.isEmpty()) { // 棧爲空直接入棧
29                         opes.push(temp);
30                     } else {
31                         // 若棧頂元素優先級大於或等於要入棧的元素,將棧頂元素彈出並計算,而後入棧
32                         if (isType(opes.peek()) >= isType(temp)) {
33                             int t = cal(nums.pop(), nums.pop(), opes.pop());
34                             nums.push(t);
35                         }
36                         opes.push(temp);
37                     }
38                 }
39             }
40         }
41         // 最後一個字符如果數字,未入棧
42         if (n != 0) {
43             nums.push(n);
44         }
45         while (!opes.isEmpty()) {
46             int t = cal(nums.pop(), nums.pop(), opes.pop());
47             nums.push(t);
48         }
49         System.out.println(nums.pop());
50     }
51 
52     // 返回的是運算符的優先級,數字和()不須要考慮
53     public static int isType(char c) {
54         if (c == '+' || c == '-') {
55             return 1;
56         } else if (c == '*' || c == '/') {
57             return 2;
58         } else {
59             return 0;
60         }
61     }
62 
63     // 運算次序是反的,跟入棧出棧次序有關
64     public static int cal(int m, int n, char c) {
65         int sum = -987654321;
66         if (c == '+') {
67             sum = n + m;
68         } else if (c == '-') {
69             sum = n - m;
70         } else if (c == '*') {
71             sum = n * m;
72         } else if (c == '/') {
73             sum = n / m;
74         }
75         return sum;
76     }
77 }
相關文章
相關標籤/搜索