本文執行個體講述了java實現任意四則運算運算式求值演算法。分享給大家供大家參考。具體分析如下:
該程式用於計算任意四則運算運算式。如 4 * ( 10 + 2 ) + 1 的結果應該為 49。
演算法說明:
1. 首先定義運算子優先順序。我們用一個
Map<String, Map<String, String>>
來儲存優先順序表。這樣我們就可以通過下面的方式來計算兩個運算子的優先順序了:
/** * 查表得到op1和op2的優先順序 * @param op1 運算子1 * @param op2 運算子2 * @return ">", "<" 或 "=" */public String priority(String op1, String op2) { return priorityMap.get(op1).get(op2);}
2. 掃描運算式字串,每次讀入一個 token 進行處理。
使用兩個輔助棧:optStack用於儲存運算子,numStack用於儲存運算元. 我們用 '#' 作為運算式的起始和結果標誌符。
讀入一個token,如果它是數字,則壓入numStack棧中;
如果它是運算子,則取出optStack棧的棧頂元素A,將 A 與 token 進行優先順序比較。
如果 A < token,則將 token 壓入optStack棧。
如果 A = token,則說明 token和A是一對括弧,此時將optStack棧的棧頂元素彈出。
如果 A > token,則從numStack中彈出2個運算元,從optStack中彈出1個運算子,並計算結果。
當optStrack棧為空白時(即棧頂元素為 '#'),numStack棧的棧頂元素即為運算式的值。
演算法實現:
/** * 算術運算式求值。 * 3 + 4 * 12 結果為51 * @author whf * */public class EvaluateExpression { // 運算子優先順序關係表 private Map<String, Map<String, String>> priorityMap = new HashMap<String, Map<String, String>>(); private LinkedStack<String> optStack = new LinkedStack<String>(); // 運算子棧 private LinkedStack<Double> numStack = new LinkedStack<Double>(); // 運算元棧 /** * 計算運算式 * @param exp 四則運算運算式, 每個符號必須以空格分隔 * @return */ public double calcualte(String exp) { StringTokenizer st = new StringTokenizer(exp); while (st.hasMoreTokens()) { String token = st.nextToken(); process(token); } return numStack.pop(); } /** * 讀入一個符號串。 * 如果是數字,則壓入numStack * 如果是運算子,則將optStack棧頂元素與該運算子進行優先順序比較 * 如果棧頂元素優先順序低,則將運算子壓入optStack棧,如果相同,則彈出左括弧,如果高,則取出2個數字,取出一個運算子執行計算,然後將結果壓入numStack棧中 * @param token */ private void process(String token) { while (false == "#".equals(optStack.getTop()) || false == token.equals("#")) { // token is numeric if (true == isNumber(token)) { numStack.push(Double.parseDouble(token)); break; // token is operator } else { String priority = priority(optStack.getTop(), token); if ("<".equals(priority)) { optStack.push(token); break; } else if ("=".equals(priority)) { optStack.pop(); break; } else { double res = calculate(optStack.pop(), numStack.pop(), numStack.pop()); numStack.push(res); } } } } /** * 執行四則運算 * @param opt * @param n1 * @param n2 * @return */ private double calculate(String opt, double n1, double n2) { if ("+".equals(opt)) { return n2 + n1; } else if ("-".equals(opt)) { return n2 - n1; } else if ("*".equals(opt)) { return n2 * n1; } else if ("/".equals(opt)) { return n2 / n1; } else { throw new RuntimeException("unsupported operator:" + opt); } } /** * 檢查一個String是否為數字 * @param token * @return */ private boolean isNumber(String token) { int LEN = token.length(); for (int ix = 0 ; ix < LEN ; ++ix) { char ch = token.charAt(ix); // 跳過小數點 if (ch == '.') { continue; } if (false == isNumber(ch)) { return false; } } return true; } /** * 檢查一個字元是否為數字 * @param ch * @return */ private boolean isNumber(char ch) { if (ch >= '0' && ch <= '9') { return true; } return false; } /** * 查表得到op1和op2的優先順序 * @param op1 運算子1 * @param op2 運算子2 * @return ">", "<" 或 "=" */ public String priority(String op1, String op2) { return priorityMap.get(op1).get(op2); } /** * 構造方法,初始化優先順序表 */ public EvaluateExpression() { // initialize stack optStack.push("#"); // initialize priority table // + Map<String, String> subMap = new HashMap<String, String>(); subMap.put("+", ">"); subMap.put("-", ">"); subMap.put("*", "<"); subMap.put("/", "<"); subMap.put("(", "<"); subMap.put(")", ">"); subMap.put("#", ">"); priorityMap.put("+", subMap); // - subMap = new HashMap<String, String>(); subMap.put("+", ">"); subMap.put("-", ">"); subMap.put("*", "<"); subMap.put("/", "<"); subMap.put("(", "<"); subMap.put(")", ">"); subMap.put("#", ">"); priorityMap.put("-", subMap); // * subMap = new HashMap<String, String>(); subMap.put("+", ">"); subMap.put("-", ">"); subMap.put("*", ">"); subMap.put("/", ">"); subMap.put("(", "<"); subMap.put(")", ">"); subMap.put("#", ">"); priorityMap.put("*", subMap); // / subMap = new HashMap<String, String>(); subMap.put("+", ">"); subMap.put("-", ">"); subMap.put("*", ">"); subMap.put("/", ">"); subMap.put("(", "<"); subMap.put(")", ">"); subMap.put("#", ">"); priorityMap.put("/", subMap); // ( subMap = new HashMap<String, String>(); subMap.put("+", "<"); subMap.put("-", "<"); subMap.put("*", "<"); subMap.put("/", "<"); subMap.put("(", "<"); subMap.put(")", "="); //subMap.put("#", ">"); priorityMap.put("(", subMap); // ) subMap = new HashMap<String, String>(); subMap.put("+", ">"); subMap.put("-", ">"); subMap.put("*", ">"); subMap.put("/", ">"); //subMap.put("(", "<"); subMap.put(")", ">"); subMap.put("#", ">"); priorityMap.put(")", subMap); // # subMap = new HashMap<String, String>(); subMap.put("+", "<"); subMap.put("-", "<"); subMap.put("*", "<"); subMap.put("/", "<"); subMap.put("(", "<"); //subMap.put(")", ">"); subMap.put("#", "="); priorityMap.put("#", subMap); }}
程式測試:
String exp = "4 * ( 10 + 2 ) + 1 #";EvaluateExpression ee = new EvaluateExpression();out.println(ee.calcualte(exp));
運行結果為 49。
希望本文所述對大家的C++程式設計有所協助。