數據結構與算法 Java實現計算後綴表達式(逆波蘭表達式)

前面我們介紹了什麼是中綴、前綴和後綴表達式,還實現使用Java代碼了中綴表達式轉後綴表達式。這篇博客我們來介紹如何計算後綴表達式,並使用Java實現。

計算後綴表達式的流程:

  • 從左至右掃描表達式,遇到數字時,將數字壓入堆棧。

  • 遇到運算符時,彈出棧頂的兩個數,用運算符對它們做相應的計算(次頂元素 和 棧頂元素),並將結果入棧。

  • 重複上述過程直到表達式最右端,最後運算得出的值即爲表達式的結果。

  • 代碼示例:

import java.util.HashMap;
import java.util.Map;
import java.util.Stack;

public class Calculator {

    //存儲運算符和優先值鍵值對
    static Map<Character, Integer> ops = new HashMap<>();
    static {
        //ops.put('(', 0);
        ops.put('+', 1);
        ops.put('-', 1);
        ops.put('*', 2);
        ops.put('/', 2);
    }

    public static Character getComputingResult(String expression){
        Stack<Character> tempStack = transferNifixExpressionToPostfixExpression(expression);
        Stack<Character> postfixExpressionStack = new Stack<>();
        //這裏千萬不能用size()遍歷棧,因爲棧的大小一直在變小。
        int count = tempStack.size();
        for (int i = 0;i < count;i ++){
            postfixExpressionStack.push(tempStack.pop());
        }
        Stack<Character> numberStack = new Stack<>();
        char temp = 0;
        int tempNum = 0;
        int fNumber = 0;
        int sNumber = 0;
        //處理從後綴表達式棧中彈出來的每個字符
        for (int i = 0;i < count;i ++){
            temp = postfixExpressionStack.pop();
            //如果字符爲數字壓入數字棧
            if(temp >= 48 && temp <= 57){
                numberStack.push(temp);
            }else {
                //這裏需要注意運算數的前後順序
                sNumber = Integer.valueOf(String.valueOf(numberStack.pop()));
                fNumber = Integer.valueOf(String.valueOf(numberStack.pop()));
                //如果計算結果超過9,需要另外實現
                if(temp == '+'){
                    tempNum = fNumber + sNumber;
                }else if(temp == '-'){
                    tempNum = fNumber - sNumber;
                }else if(temp == '*'){
                    tempNum = fNumber * sNumber;
                }else if(temp == '/'){
                    //這裏需要注意,因爲實現的是簡易版計算,這裏的計算結果如果爲浮點類型自動被截取爲整數
                    tempNum = fNumber / sNumber;
                }
                numberStack.push(String.valueOf(tempNum).charAt(0));
            }
        }
        return numberStack.pop();
    }

    private static Stack<Character> transferNifixExpressionToPostfixExpression(String nifixExpression){
        //存儲表達式的中間結果
        Stack<Character> expStack = new Stack<>();
        //存儲運算符
        Stack<Character> opStack = new Stack<>();
        //把中綴表達式字符串轉換爲字符數組
        char [] chars = new char[nifixExpression.length()];
        nifixExpression.getChars(0, nifixExpression.length(), chars, 0);
        //遍歷數組,處理每一個表達式的字符
        for(int i = 0;i < chars.length;i ++){
            if(chars[i] >= 48 && chars[i] <= 57){
                expStack.push(chars[i]);
            }else {
                if(opStack.isEmpty() || opStack.peek() == '('){
                    opStack.push(chars[i]);
                }else {
                    if(chars[i] == '('){
                        opStack.push(chars[i]);
                    }else if(chars[i] == ')'){
                        while (opStack.peek() != '('){
                            expStack.push(opStack.pop());
                        }
                        opStack.pop();
                    }else {
                        while (ops.get(chars[i]) <= ops.get(opStack.peek())){
                            expStack.push(opStack.pop());
                            if(opStack.size() == 0)break;
                        }
                        opStack.push(chars[i]);
                    }
                }
            }
        }
        opStack.forEach(character -> {
            expStack.push(character);
        });
//        StringBuilder stringBuilder = new StringBuilder("");
//        expStack.forEach(character -> {
//            stringBuilder.append(character);
//        });
        return expStack;
    }

    public static void main(String[] args) {
        System.out.println(getComputingResult("(5+2)*1-4"));
    }
}
  • 輸出:
3
  • 注意這裏是實現的簡易版計算器,全程計算只支持一位整數。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章