數據結構——棧(中綴表達式轉後綴表達式)

波蘭計算器——後綴表達式

對於一個表達式,在我們生活中是這樣表示的: 1+((2+3)x4)-5 。也就是我們所說的中綴表達是 ,但是這對於計算機而言,這樣計算是很複雜的,具體思路以及代碼見上一篇博客:
棧實現計算器(中綴表達式)
所以,在計算器中使用的是後綴表達式——逆波蘭表達式
那麼如何實現從中綴表達式轉換成後綴表達式呢?以下爲實現思路:
中綴表達式轉換成後綴表達式流程

代碼:

package cn.littleworm.波蘭計數器;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

public class PolandNotation {

    public static void main(String[] args) {
        String ex = "1+((2+3)*4)-5";
        List<String> list = toInfixExperssionList(ex);
        System.out.println(list);
        List<String> list1 = parseSuffixException(list);
        System.out.println(list1);

    }

    //首先將中綴表達式顯示在list集合中
    public static List<String> toInfixExperssionList(String s){
        /*
            思路:
                1、傳過來的是一個表達式字符串
                2、定義一個指針索引,用來遍歷表達式
                3、要考慮的一個因素就是,如果數字,判斷書是否是多位數

         */
        List<String> list = new ArrayList<>();
        int i = 0;  //定義指針索引
        String keeper;  //用於拼接字符串
        char ch;    //用來接收字符
        do {
            ch = s.charAt(i);
            //判斷是否是符號
            if (ch<48||ch>57){  //證明不是數字
                list.add(ch+"");
                i++;
            }else {
                //先將keeper置爲空
                keeper = "";
                while (i<s.length()&&(ch=s.charAt(i))>=48&&(ch=s.charAt(i))<=57){
                    keeper+=ch;
                    i++;    //自增
                }
                //加到集合中
                list.add(keeper);
            }

        }while (i<s.length());

        return list;
    }



  

    //將中綴表達式轉換成後綴表達式
    public static List<String> parseSuffixException(List<String> listExc){
        //初始化符號棧
        Stack<String> s1 = new Stack<>();

        //創建一個list集合用來接收中間結果
        List<String> s2 = new ArrayList<>();

        //遍歷listExc表達式
        for (String item : listExc) {
            //如果是一個數,直接加入
            if (item.matches("\\d+")){  //這裏使用正則表達式,用來匹配多爲數字
                s2.add(item);
            }else if (item.equals("(")){
                //如果是左括號,s1直接加入
                s1.push(item);
            }else if (item.equals(")")){
                //如果是左括號,依次彈出符號棧s1中的運算符,並壓入到s2中,直到遇到右括號“(”
                // 將這一對括號全部丟掉
                while (!"(".equals(s1.peek())){
                    String pop = s1.pop();
                    s2.add(pop);
                }
                //當執行完上面的循環之後,棧頂指針就是指向左括號,所以要將左括號彈出去
                s1.pop();
            }else {
                //如果是符號
                //現在要判斷當前符號的優先級是否小於等於棧頂符號,所以這時需一個比較優先級的方法
                while (s1.size()>0&&Operation.getValue(s1.peek())>=Operation.getValue(item)){
                    String pop = s1.pop();
                    s2.add(pop);
                }

                //如果當前運算符小於或者是符號棧爲空
                s1.push(item);
            }

        }
        //當上面的循環都結束了,這時將符號棧中的數據依次pop出,並添加到s2中
        while (s1.size()!=0){
            String pop = s1.pop();
            s2.add(pop);
        }
        return s2;

    }

}
//內部類,來判斷運算符號的優先級
class Operation{
    private static int ADD = 1;
    private static int SUB = 1;
    private static int MUL = 2;
    private static int DIV = 2;

    //創建方法、
    public static int getValue(String operation){
        int result = 0;
        switch (operation){
            case "+":result = ADD;break;
            case "-":result = SUB;break;
            case "*":result = MUL;break;
            case "/":result = DIV;break;
            default:
                System.out.println("不存在這樣的運算符");
                break;
        }
        return result;
    }


}

結果展示:

結果展示

注:在其他的資料中,都是初始化兩個棧,一個是符號棧,一個是數據棧,執行到最後的時候,要將數據棧倒敘輸出就是後綴表達式了,但是在本篇博客中對於數據棧使用list集合來代替,因爲list集合比棧更容易操作!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章