數據結構與算法 中綴、前綴和後綴表達式,Java實現中綴轉後綴

中綴表達式

  • 中綴表達式是一個通用的算術或邏輯公式表示方法, 操作符是以中綴形式處於操作數的中間(例:3 + 4),中綴表達式是人們常用的算術表示方法。中綴記法中括號是必需的。計算過程中必須用括號將操作符和對應的操作數括起來,用於指示運算的次序。
  1. 8+4-62用後綴表達式表示爲:8 4+6 2-
  2. 2*(3+5)+7/1-4用後綴表達式表示爲:235+*71/+4-

前綴表達式

  • 前綴表達式是一種沒有括號的算術表達式,與中綴表達式不同的是,其將運算符寫在前面,操作數寫在後面。爲紀念其發明者波蘭數學家Jan Lukasiewicz,前綴表達式也稱爲“波蘭式”。例如,- 1 + 2 3,它等價於1-(2+3)。
  • 作用:前綴表達式是一種十分有用的表達式,將中綴表達式轉換爲前綴表達式後,就可以只依靠出棧、入棧兩種簡單操作完全解決中綴表達式的全部運算。

後綴表達式

  • 一個表達式E的後綴形式可以如下定義:
  1. 如果E是一個變量或常量,則E的後綴式是E本身。
  2. 如果E是E1 op E2形式的表達式,這裏op是任何二元操作符,則E的後綴式爲E1’E2’ op,這裏E1’和E2’分別爲E1和E2的後綴式。
  3. 如果E是(E1)形式的表達式,則E1的後綴式就是E的後綴式。
  • 如:我們平時寫a+b,這是中綴表達式,寫成後綴表達式就是:ab+
    在這裏插入圖片描述
  • 作用:
    實現逆波蘭式的算法,難度並不大,但爲什麼要將看似簡單的中序表達式轉換爲複雜的逆波蘭式?原因就在於這個簡單是相對人類的思維結構來說的,對計算機而言中序表達式是非常複雜的結構。相對的,逆波蘭式在計算機看來卻是比較簡單易懂的結構。因爲計算機普遍採用的內存結構是棧式結構,它執行先進後出的順序。

中綴表達式轉後綴表達式:

在這裏插入圖片描述
在這裏插入圖片描述

  • 示例說明:
    將中綴表達式“1+((2+3)×4)-5”轉換爲後綴表達式的過程如下:
    在這裏插入圖片描述
    因此結果爲 :“1 2 3 + 4 × + 5 –”

  • 示例代碼:

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

public class Calculator {
    public static int getComputingResult(String expression){
        return 0;
    }

    private static String transferNifixExpressionToPostfixExpression(String nifixExpression){
        //存儲表達式的中間結果
        Stack<Character> expStack = new Stack<>();
        //存儲運算符
        Stack<Character> opStack = new Stack<>();
        //存儲運算符和優先值鍵值對
        Map<Character, Integer> ops = new HashMap<>();
//        ops.put('(', 0);
        ops.put('+', 1);
        ops.put('-', 1);
        ops.put('*', 2);
        ops.put('/', 2);
        //把中綴表達式字符串轉換爲字符數組
        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 stringBuilder.toString();
    }

    public static void main(String[] args) {
        System.out.println(transferNifixExpressionToPostfixExpression("1+((2+3)*4)-5"));
    }

}
  • 輸出:
123+4*+5-
  • 注意,如果想把"運算符棧爲空或者棧頂元素爲’('把運算符直接壓入棧" 的條件改爲"運算符棧爲空把運算符直接壓入棧",可以把’('運算符的優先級設置爲最低。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章