在 Java 資料結構與演算法的學習中,中綴表達式轉後綴表達式(逆波蘭表示法)是經典且重要的課題。中綴表達式符合人類閱讀習慣(如 A + B),但電腦解析較為複雜;後綴表達式則適合機器運算,透過堆疊即可高效求值。本文將詳細解析轉換原理,並提供完整的 Java 實作代碼。
中綴轉後綴的核心演算法由艾茲赫爾·戴克斯特拉提出,主要步驟如下:
(,壓入堆疊),彈出堆疊直到遇到左括號| 運算子 | 優先級 | 結合性 |
|---|---|---|
| +、- | 1(最低) | 左結合 |
| *、/ | 2 | 左結合 |
| ( | 3(特殊) | — |
| ) | 4(觸發彈出) | — |
// 堆疊實作
public class StackX {
private int top;
private char[] stackArray;
private int maxSize;
public StackX(int maxSize) {
this.maxSize = maxSize;
this.top = -1;
stackArray = new char[this.maxSize];
}
public void push(char item) { stackArray[++top] = item; }
public char pop() { return stackArray[top--]; }
public char peek() { return stackArray[top]; }
public boolean isEmpty() { return (top == -1); }
public int size() { return top + 1; }
}
// 中綴轉後綴核心類
public class InToPost {
private StackX stack;
private String input;
private String output = "";
public InToPost(String input) {
this.input = input;
stack = new StackX(input.length());
}
public String doTrans() {
for (int i = 0; i < input.length(); i++) {
char ch = input.charAt(i);
switch (ch) {
case '+': case '-': getOp(ch, 1); break;
case '*': case '/': getOp(ch, 2); break;
case '(': getOp(ch, 3); break;
case ')': getOp(ch, 4); break;
default: output += ch; // 運算元直接輸出
}
}
while (!stack.isEmpty()) {
output += stack.pop();
}
return output;
}
private void getOp(char op, int prec) {
char topOp;
if (stack.isEmpty() || prec == 3) {
stack.push(op);
} else if (prec == 4) { // 遇到右括號
while (!stack.isEmpty()) {
topOp = stack.pop();
if (topOp == '(') break;
output += topOp;
}
} else if (prec == 1) { // + -
topOp = stack.peek();
if (topOp == '(') stack.push(op);
else { output += stack.pop(); stack.push(op); }
} else { // * /
topOp = stack.peek();
if (topOp == '(' || topOp == '+' || topOp == '-') stack.push(op);
else output += stack.pop();
}
}
}
// 測試類
public class TestInToPost {
public static void main(String[] args) {
String expr = "((A+B)*C)-D";
InToPost translator = new InToPost(expr);
System.out.println("中綴: " + expr);
System.out.println("後綴: " + translator.doTrans());
// 輸出: AB+C*D-
}
}
輸入 ((A+B)*C)-D,轉換過程如下:
A、B 直接輸出 → AB+ 進堆疊) 彈出 + → AB+* 進堆疊C 輸出 → AB+C) 彈出 * → AB+C*- 進堆疊D 輸出 → AB+C*D- → AB+C*D-本實作為教學示範版本,存在以下限制:
A、1),不支援多位數或變數名生產環境建議使用 ScriptEngine 或成熟庫(如 exp4j、JEP)處理複雜表達式解析。
中綴轉後綴是編譯原理與資料結構的基石應用。掌握堆疊對運算子優先級的管理邏輯,不僅能解決表達式求值問題,更能深入理解編譯器前端的語法分析機制。建議讀者嘗試擴展支援多位數、函數呼叫等特性,以鞏固演算法功力。