java中的棧Stack的基本使用和應用(二) ——利用棧計算合法的算術表達,中綴表達式轉后綴表達式


利用棧Stack計算合法的算術表達式

限定的算術表達式求值問題:包含  “+”、“-”、“*”、“/”  、正整數和圓括號的合法算術表達式。

算術表達式轉化成后綴表達式

程序語言中,運算符在兩個運算數中間稱為中綴表達式,即我們常用的表達方法,例如 1+2*3。

在中綴表達式中要考慮運算的優先級,先乘除,后加減,從左到右,還有括號內先運算。

在后綴表達式中已經考慮了運算符的優先級,並且沒有括號,只有運算數和運算符。

例如上述例子 1+2*3 ,中綴表達式計算時,根據優先級,先計算2*3=6,再計算1+6=7

轉換成后綴表達式   1+2*3 => 123*+ ,

從左到右掃描第一個運算符為 * ,先執行2*3;第二個運算符為 + ,執行1+6.

中綴表達式轉后綴表達式過程

①初始化exp字符數組、resultExp字符數組(可變)、operator棧

  exp字符數組:存放,合法的算術表達式

  resultExp字符數組(可變):存放后綴表達式

  operator棧:存放運算符,並將 “=” 作為棧底元素

②從exp讀取字符ch,若為運算數將后續運算數依次存放入resultExp中,並以#標志數值結束

③若ch為運算符,將其和operator棧頂中的運算符進行比較優先級比較

  ch優先級大於棧頂運算符優先級,則ch進棧

  ch優先級小於棧頂運算符優先級,則棧中運算符退棧,直至ch運算符大於棧頂運算符,ch再進棧。

  ch優先級等於棧頂運算符優先級,特殊情況,只有括號滿足該情況,即“)”的優先級 等於“(”的優先級,將(退棧。

④exp掃描完畢,此時operator棧不空,則將 “=” 之前所有的運算符退棧並放入resultExp中

復雜一點的例子

(12-3)/(4+5)

算法如下:

package com.xumz.stack;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;
/**
 * 中綴表達式轉后綴表達式
 * 
 * @author xumz 2017/10/18
 */
public class ExpressionChange {
    // 存放左運算符的優先級
    Map<Character, Integer> leftOperator = new HashMap<Character, Integer>() {
        {
            put('=', 0);
            put('(', 1);
            put('+', 3);
            put('-', 3);
            put('*', 5);
            put('/', 5);
            put(')', 6);
        }
    };
    // 存放右運算符的優先級
    Map<Character, Integer> rightOperator = new HashMap<Character, Integer>() {
        {
            put('=', 0);
            put('(', 6);
            put('+', 2);
            put('-', 2);
            put('*', 4);
            put('/', 4);
            put(')', 1);
        }
    };

    /**
     * 中綴轉后綴
     * 
     * @param str
     * @return
     */
    public String trans(String str) {
        // 轉換成char[]
        char[] exp = str.toCharArray();
        // 存放轉換結果
        List<Character> resultExp = new ArrayList<Character>();
        // 存放運算符,初始底為‘=’
        Stack<Character> operator = new Stack<Character>();
        operator.push('=');
        // 掃描exp表達式
        int i = 0;
        while (i != exp.length) {
            // 數字情況
            if (!isOperator(exp[i])) {
                while (i != exp.length && !isOperator(exp[i])) {
                    resultExp.add(exp[i]);
                    i++;
                }
                resultExp.add('#');
            }
            // 運算符情況
            else {
                switch (compareOperatorNice(operator.peek(), exp[i])) {
                case -1:
                    operator.push(exp[i]);
                    i++;// 繼續下一個字符
                    break;
                case 0:
                    operator.pop();
                    i++;// 繼續下一個字符
                    break;
                case 1:
                    resultExp.add(operator.peek());
                    operator.pop();
                    break;
                }
            }

        }
        while (!(operator.peek()=='=')) {
            resultExp.add(operator.peek());
            operator.pop();
        }
        

        // 轉換為String返回
        return resultExp.toString();
    }

    boolean isOperator(char ch) {
        if (leftOperator.containsKey(ch)) {
            return true;
        }
        return false;
    }

    /**
     * 比較左右運算符優先級,返回狀態結果
     * 
     * @param leftOperator
     * @param rightOperator
     * @return
     */
    int compareOperatorNice(char left, char right) {
        if (leftOperator.get(left) == rightOperator.get(right)) {
            return 0;
        }
        if (leftOperator.get(left) < rightOperator.get(right)) {
            return -1;
        }
        return 1;
    }

}
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM