我推薦他用中序轉後序的方式去處理,不過他似乎不太瞭解
所以我就直接幫他分析一下程式碼
這次程式碼是由良葛格的『中序式轉後序式(前序式)』及『 後序式的運算』複製過來的XD
分別由『Calculator』及『Infix』所組成的,Infix類別是在做『中序轉前序』或『中序轉後序』
Calculator則是提供輸入四則運算以及運算的類別
觀念部份,改天補上
import java.util.*; import static java.lang.System.out; public class Calculator { // 處理運算 private static double cal(char op, double p1, double p2) { switch (op) { case '+': return p1 + p2; case '-': return p1 - p2; case '*': return p1 * p2; case '/': return p1 / p2; default: throw new ArithmeticException(op + " not defined"); } } public static double eval(String expr) { // 鍊結串列 LinkedListstack = new LinkedList (); // 依序輸出字元 for (char c : Infix.toPostfix(expr).toCharArray()) { // 如果是運算符號,則取最後兩個數字運算;否則將數字儲存至堆疊 if ("+-*/".indexOf(c) != -1) { double p2 = stack.removeLast(); double p1 = stack.removeLast(); stack.add(cal(c, p1, p2)); } else { stack.add(Double.parseDouble(String.valueOf(c))); } } // 傳回堆疊最後一個值,即為運算結果 return stack.getLast(); } public static void main(String[] args) { System.out.println(eval("5+0*8/8")); } }
import java.util.*; public class Infix { // 優先順序 +- = 1, */ = 2, other = 0 private static int priority(char c) { return c == '+' || c == '-' ? 1 : c == '*' || c == '/' ? 2 : 0; } private static String toPostfix(String infix, boolean isPost) { // 如果為後序就不用反轉,前序則需要反轉 String expr = isPost ? infix : new StringBuffer(infix).reverse() .toString(); // 字元 LinkedListstack = new LinkedList (); StringBuilder output = new StringBuilder(); // 是則為( 不是則為) char toStack = isPost ? '(' : ')'; // 是則為) 不是則為( char toOutput = isPost ? ')' : '('; for (char c : expr.toCharArray()) { if (c == toStack) { // 加入 ( 或 ) stack.add(c); } else if ("+-*/".indexOf(c) != -1) { // 加入運算符號 // 堆疊不為空,且優先權沒有大於,則移除並加入到output while (!stack.isEmpty() && priority(stack.getLast()) >= priority(c)) { output.append(stack.removeLast()); } // 加入運算符號 stack.add(c); } else if (c == toOutput) { // 加入 ) 或 ( // 不 等於( 或 ) 則加入output while (stack.getLast() != toStack) { output.append(stack.removeLast()); } stack.removeLast(); } else { // 加入數字 output.append(c); } } // 堆疊不為空,不斷回傳最後一個值並且刪除 while (!stack.isEmpty()) { output.append(stack.removeLast()); } // 如果是後序則回傳結果文字,否則傳回反轉文字 return isPost ? output.toString() : output.reverse().toString(); } // 後序 public static String toPostfix(String infix) { return toPostfix(infix, true); } // 前序 public static String toPrefix(String infix) { return toPostfix(infix, false); } }
參考資料:
中序式轉後序式(前序式)
後序式的運算