1. 程式人生 > 其它 >4-2中綴表示式轉字尾

4-2中綴表示式轉字尾

中綴表示式轉字尾


基本介紹

將中綴表示式轉成字尾表示式。
具體步驟如下:

  1. 初始化兩個棧: 運算子棧s1 和 儲存中間結果的棧s2;

  2. 從左至右掃描中綴表示式;

  3. 遇到運算元時,將其壓s2;

  4. 遇到運算子時,比較其與s1棧頂運算子的優先順序:

    (1)如果s1為空,或棧頂運算子為左括號“(”,則直接將此運算子入棧;

​ (2)否則,若優先順序比棧頂運算子的高,也將運算子壓入s1;

​ (3)否則,將s1棧頂的運 算符彈出並壓入到s2中,再次轉到 (4-1) 與s1中新的棧頂運算
符相比較;

  1. 遇到括號時:
    (1)如果是左括號“(”, 則直接壓入s1
    (2)如果是右括號“)”,則依次彈出s1棧頂的運算子,並壓入s2,直到遇到左括號為
    止,此時將這一對括號丟棄
  2. 重複步驟2至5,直到表示式的最右邊
  3. 將s1中 剩佘的運算子依次彈出並壓入s2.
  4. 依次彈出s2中的元素並輸出,結果的逆序即為中綴表示式對應的字尾表示式

案例

package com.company.stack;

import java.beans.Expression;
import java.util.List;
import java.util.Queue;
import java.util.Stack;

/**
 * @Function :
 * date 2021/5/9 - 15:50
 *
 * How :
 */
public class PolandNotation {
    public static void main(String[] args) {
        //給定逆波蘭表示式
        // (3+10)*100-6   ===》 3 10 + 100 * 600 -
        String stringExpression = "( 3 + 10 ) * 100 - 600";
        String[] Exp = stringExpression.split(" ");
        String[] strings = parseSuffixExpression(Exp);
        System.out.println("字尾表示式:");
        for (String a: strings){
            System.out.printf(a+"\t");
        }
        int calculate = calculate(strings);
        System.out.println();
        System.out.println("計算結果是:"+calculate);
    }
    //轉字尾表示式
    public static String[] parseSuffixExpression(String[] exp){
        //定義符號棧 s1  和 中間結果棧 s2
        Stack<String> st1 = new Stack<>();
        //實際使用中可以將其轉化為list  方便輸出 不用逆序
        Stack<String> st2 = new Stack<>();
        
        //遍歷字串陣列
        for ( String temp : exp ) {
            //如果是數字 入數字棧
            if (temp.matches("\\d+")){
                st2.push(temp);
            }else if (st1.size()==0 || temp.equals("(")){
                st1.push(temp);
            }else if (temp.equals(")")) {
                while (!st1.peek().equals("(")){
                    st2.push(st1.pop());
                }
                st1.pop();  //消除小括號
            }else {
                //當item的優先順序小於等於s1棧頂運算子,將s1棧項的運算子彈出併到s2中, 再次轉到(4.1)與s1中新的棧項運算子相比較
                while (st1.size() != 0 && ( getOpration(st1.peek()) >= getOpration(temp) ) ) {
                    st2.push(st1.pop());
                }
                st1.push(temp);
            }
        }

        while (st1.size() != 0){
            st2.push(st1.pop());
        }
        int len = exp.length-3;
        String[] str = new String[len+1];
        for (int i = len; i >=0; i--) {
            str[i] = st2.pop();
        }
        return str;
    }
    //字尾表示式計算
    public static int calculate( String[] lis){
        //建立給棧,只需要一個棧即可
        Stack <String> stack = new Stack<String>();
        //遍歷ls
        for(String item: lis){
            //這裡使用正則表示式來取出數
            if (item.matches("\\d+")) { //匹配的是多位數
                //入棧
                stack.push(item);
            }else {
                int num1 = Integer.parseInt(stack.pop());
                int num2 = Integer.parseInt(stack.pop());
                int res = 0;
                if (item.equals("+")){
                    res = num1+num2;
                }else if (item.equals("-")){
                    res = num2 - num1;
                }else if (item.equals("*")){
                    res = num1*num2;
                }else if (item.equals("/")){
                    res = num2/num1;
                }else {
                    throw new RuntimeException("輸入符號錯誤");
                }
                stack.push(String.valueOf(res));
            }
        }
        return Integer.parseInt(stack.pop());
    }

    public static int getOpration(String str){
        int level = 0;
        switch (str){
            case "+":
                level = 1;
                break;
            case "-":
                level = 1;
                break;
            case "*":
                level = 2;
                break;
            case "/":
                level = 2;
                break;
            case "(":
                level = 0;
                break;
            case ")":
                level = 0;
                break;
            default:
                throw new RuntimeException("錯誤的符號");
        }
        return level;
    }

}