前綴表達式、中綴表達式、後綴表達式都是四則運算的表達方式,用以四則運算表達式求值
,即數學表達式的求職express
中綴表達式就是常見的運算表達式,如(3+4)×5-6code
前綴表達式又稱波蘭式,前綴表達式的運算符位於操做數以前字符串
好比:- × + 3 4 5 6get
從右至左掃描表達式,遇到數字時,將數字壓入堆棧,遇到運算符時,彈出棧頂的兩個數,用運算符對它們作相應的計算(棧頂元素 op 次頂元素),並將結果入棧;重複上述過程直到表達式最左端,最後運算得出的值即爲表達式的結果數學
- 從右至左掃描,將六、五、四、3壓入堆棧
- 遇到+運算符,所以彈出3和4(3爲棧頂元素,4爲次頂元素,注意與後綴表達式作比較),計算出3+4的值,得7,再將7入棧
- 接下來是×運算符,所以彈出7和5,計算出7×5=35,將35入棧
- 最後是-運算符,計算出35-6的值,即29,由此得出最終結果
轉換步驟以下:it
例如:1+((2+3)×4)-5具體過程,以下表io
掃描到的元素 | S2(棧底->棧頂) | S1 (棧底->棧頂) | 說明 |
---|---|---|---|
5 | 5 | 空 | 數字,直接入棧 |
- | 5 | - | s1爲空,運算符直接入棧 |
) | 5 | -) | 右括號直接入棧 |
4 | 5 4 | -) | 數字直接入棧 |
x | 5 4 | -)x | s1棧頂是右括號,直接入棧 |
) | 5 4 | -)x) | 右括號直接入棧 |
3 | 5 4 3 | -)x) | 數字 |
+ | 5 4 3 | -)x)+ | s1棧頂是右括號,直接入棧 |
2 | 5 4 3 2 | -)x)+ | 數字 |
( | 5 4 3 2 + | -)x | 左括號,彈出運算符直至遇到右括號 |
( | 5 4 3 2 + x | - | 同上 |
+ | 5 4 3 2 + x | -+ | 優先級與-相同,入棧 |
1 | 5 4 3 2 + x 1 | -+ | 數字 |
到達最左端 | 5 4 3 2 + x 1 + - | 空 | s1剩餘運算符 |
結果是:- + 1 × + 2 3 4 5table
後綴表達式又稱逆波蘭表達式,與前綴表達式類似,只是運算符位於操做數以後class
好比:3 4 + 5 × 6 -求職
與前綴表達式相似,只是順序是從左至右:
從左至右掃描表達式,遇到數字時,將數字壓入堆棧,遇到運算符時,彈出棧頂的兩個數,用運算符對它們作相應的計算(次頂元素 op 棧頂元素),並將結果入棧;重複上述過程直到表達式最右端,最後運算得出的值即爲表達式的結果
例如後綴表達式「3 4 + 5 × 6 -」:
與轉換爲前綴表達式類似,步驟以下:
例如,將中綴表達式「1+((2+3)×4)-5」轉換爲後綴表達式的過程以下:
掃描到的元素 | s2(棧底->棧頂) | s1 (棧底->棧頂) | 說明 |
---|---|---|---|
1 | 1 | 空 | 數字,直接入棧 |
+ | 1 | + | s1爲空,運算符直接入棧 |
( | 1 | + ( | 左括號,直接入棧 |
( | 1 | + ( ( | 同上 |
2 | 1 2 | + ( ( | 數字 |
+ | 1 2 | + ( ( + | s1棧頂爲左括號,運算符直接入棧 |
3 | 1 2 3 | + ( ( + | 數字 |
) | 1 2 3 + | + ( | 右括號,彈出運算符直至遇到左括號 |
× | 1 2 3 + | + ( × | s1棧頂爲左括號,運算符直接入棧 |
4 | 1 2 3 + 4 | + ( × | 數字 |
) | 1 2 3 + 4 × | + | 右括號,彈出運算符直至遇到左括號 |
- | 1 2 3 + 4 × + | - | -與+優先級相同,所以彈出+,再壓入- |
5 | 1 2 3 + 4 × + 5 | - | 數字 |
到達最右端 | 1 2 3 + 4 × + 5 - | 空 | s1中剩餘的運算符 |
所以結果爲「1 2 3 + 4 × + 5 -」
public class Operation { private static int ADDITION=1; private static int SUBTRACTION=1; private static int MULTIPLICATION=2; private static int DIVISION=2; public static int getValue(String operation){ int result; switch (operation){ case "+": result=ADDITION; break; case "-": result=SUBTRACTION; break; case "*": result=MULTIPLICATION; break; case "/": result=DIVISION; break; default: // System.out.println("不存在該運算符"); result=0; } return result; } } public class PolishNotation { public static void main(String[] args) { Scanner sc=new Scanner(System.in); System.out.println("請輸入運算表達式:"); String expressionStr=sc.nextLine(); // System.out.println(expressionStr); List<String> zx= toInfixExpression(expressionStr); List<String> rpn=parseSuffixExpression(zx); String rpnStr=""; for(String str:rpn){ rpnStr+=str; } System.out.println(rpnStr); System.out.println("計算結果:"+ calculate(rpn)); } /** * 把字符串轉換成中序表達式 * @param s * @return */ public static List<String> toInfixExpression(String s) { List<String> ls = new ArrayList<String>();//存儲中序表達式 int i = 0; String str; char c; do { if ((c = s.charAt(i)) < 48 || (c = s.charAt(i)) > 57) { ls.add("" + c); i++; } else { str = ""; while (i < s.length() && (c = s.charAt(i)) >= 48 && (c = s.charAt(i)) <= 57) { str += c; i++; } ls.add(str); } } while (i < s.length()); return ls; } /** * 轉換成逆波蘭表達式 * @param ls * @return */ public static List<String> parseSuffixExpression(List<String> ls) { Stack<String> s1=new Stack<String>(); Stack<String> s2=new Stack<String>(); List<String> lss = new ArrayList<String>(); for (String ss : ls) { if (ss.matches("\\d+")) { lss.add(ss); } else if (ss.equals("(")) { s1.push(ss); } else if (ss.equals(")")) { while (!s1.peek().equals("(")) { lss.add(s1.pop()); } s1.pop(); } else { while (s1.size() != 0 && Operation.getValue(s1.peek()) >= Operation.getValue(ss)) { lss.add(s1.pop()); } s1.push(ss); } } while (s1.size() != 0) { lss.add(s1.pop()); } return lss; } /** * 經過逆波蘭表達式計算結果 * @param ls * @return */ public static int calculate(List<String> ls) { Stack<String> s=new Stack<String>(); for (String str : ls) { if (str.matches("\\d+")) { s.push(str); } else { int b = Integer.parseInt(s.pop()); int a = Integer.parseInt(s.pop()); int result=0; if (str.equals("+")) { result = a + b; } else if (str.equals("-")) { result = a - b; } else if (str.equals("*")) { result = a * b; } else if (str.equals("\\")) { result = a / b; } s.push("" + result); } } System.out.println(s.peek()); return Integer.parseInt(s.pop()); } }