1. 程式人生 > 實用技巧 >中綴表示式轉逆波蘭表示式,逆波蘭表示式的計算

中綴表示式轉逆波蘭表示式,逆波蘭表示式的計算

中綴表示式轉字尾表示式:

  1. 中綴表示式,是我們人可以識別的表示式形式;

  2. 字尾表示式是計算機可以識別的表示式形式。

大體思路:

  1. 將中綴表示式的每一個符號存放在ArrayList a裡面
  2. 新建一個棧stack s來儲存中間符號,建立一個ArrayList b存放字尾表示式(為什麼不用棧呢?因為要將存入的字元遍歷,先進先出,用List更加方便)
  3. 掃描a:
    • 如果是數字,直接放入b即可;
    • 如果是符號:
      • '(' : push到s中
      • ')' : push棧s中的棧頂元素,依次存入b中,直到遇到'(',且這對括號可以被丟棄了
      • 其他運算子:比較該運算子和s棧頂元素的優先順序,若它的優先順序高,則直接放入s中;若它的優先順序<=棧頂元素的優先順序,則將棧頂元素pop出來,存入b中,別忘了此時將該運算子繼續與s棧頂元素比較
public static List<String> parseSuffixExpressionList(List<String> list) {
        //定義兩個棧
        Stack<String> s1 = new Stack<>();   //符號棧
        //s2棧沒有pop操作,需要逆序輸出,如果用棧結構比較麻煩,所以可以用陣列實現
        //Stack<String> s2 = new Stack<>();   //  儲存結果
        ArrayList<String> s2 = new
ArrayList<>(); //儲存結果 for (String ele : list) { //如果是一個數,則加入s2 if (ele.matches("\\d+")) { s2.add(ele); } else if (ele.equals("(")) { s1.push(ele); } else if (ele.equals(")")) { //如果是右括號,則依次彈出s1棧頂的運算子,並壓入s2,直到遇到左括號未知,且這對括號唄丟棄
while (!s1.peek().equals("(")) { s2.add(s1.pop()); } //左括號被彈出(消除括號) s1.pop(); } else { //操作符的優先順序 //當ele的優先順序小於等於s1棧頂運算子,將s1棧頂的運算子彈出並加入到s2,再次將ele與新的棧頂運算子比較 while (s1.size() != 0 && Operation.getValue(ele) <= Operation.getValue(s1.peek())){ s2.add(s1.pop()); } s1.push(ele); } } //將s1中的剩餘的符號依次彈出並加入到s2; while (!s1.empty()){ s2.add(s1.pop()); } return s2; }
程式碼實現

那下面寫如何計算逆波蘭表示式吧

//完成對逆波蘭表示式的運算
    public static int calculate(List<String> list) {
        //建立棧
        Stack<String> stack = new Stack<>();
        //遍歷list
        for (String s : list) {
            if (s.matches("\\d+")) {
                //匹配是多位數
                stack.push(s);
            } else {
                //pop出兩個數進行運算
                int num2 = Integer.parseInt(stack.pop());
                int num1 = Integer.parseInt(stack.pop());
                int res = 0; //存放結果
                if (s.equals("+")) {
                    res = num1 + num2;
                } else if (s.equals("-")) {
                    res = num1 - num2;
                } else if (s.equals("*")) {
                    res = num1 * num2;
                } else if (s.equals("/")) {
                    res = num1 / num2;
                } else {
                    throw new RuntimeException("運算子有誤");
                }
                stack.push(res + "");
            }
        }
        //最後留在stack中的資料是結果
        return Integer.parseInt(stack.pop());
    }
程式碼實現