題目:git
初看此題,從人的直觀角度來講很簡單,先遍歷括號內的運算完再從新遍歷,可是很麻煩。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 }