棧的應用--四則運算(中綴與后綴表達式轉換)

參考鏈接
結合原文章募狂,做了一定修改蓝厌,增加Java源碼實現(xiàn)


1. 概述

對于四則運算表達式的計算顿仇,是輸入數(shù)據(jù)結構中棧的應用淘正,即重點是中綴表達式轉換為后綴表達式


2. 后綴表達式計算

  • 為了解釋后綴表達式的好處摆马,我們先來看看,計算機是如何計算后綴表達式的
  • 后綴表達式實例9 3 1 - 3 * + 10 2 / +
  • 計算規(guī)則:從左到右遍歷表達式的每個數(shù)字和符號鸿吆,遇到數(shù)字就進棧今膊,遇到是符號,就將處于棧頂?shù)膬蓚€數(shù)字出棧伞剑,進行計算,然后計算結果進棧市埋,一直到最終獲得結果黎泣。
  • 計算過程:


    image
    image

    image

    image

3. 中綴表達式轉后綴表達式

我們把平時標準的四則運算表達式比如9+(3-1)*3+10/2叫做中綴表達式。
中綴表達式:9+(3-1)*3+10/2轉換后綴表達式9 3 1 - 3 * + 10 2 / +

  • 轉換規(guī)則
  1. 當當前字符為數(shù)字時缤谎,直接輸出抒倚;
  2. 當當前字符為(時,將其壓棧坷澡;
  3. 當當前字符為)時托呕,則彈出堆棧中最上的(之前的所有運算符并輸出,然后刪除堆棧中的(频敛;
  4. 當當前字符為運算符時项郊,則依次彈出堆棧中優(yōu)先級大于等于當前運算符的(到”(“之前為止),輸出斟赚,再將當前運算符壓棧着降;
    最后彈出所有棧中的內(nèi)容輸出
  • 轉換過程
    image

    image

    image

    image

    image

4. 源代碼實現(xiàn)

package data_structure;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 棧的應用
 * https://blog.csdn.net/u011857433/article/details/79993385
 * 四則運算表達式求職,中綴表達式與后綴表達式轉換
 */
public class ReversePoland {


    public static void main(String[] args) {

//        Calculation1("9 3 1 - 3 * + 10 2 / +");
        System.out.println(Calculation2("9 + ( 3 - 1 ) * 3 + 10 / 2"));
    }

    /**
     * 計算后綴表達式
     * @param inputString 9 3 1 - 3 * + 10 2 / + 以空格分隔
     */
    public static int Calculation1(String inputString){
        String[] input = inputString.split(" ");

        Stack<Integer> stack = new Stack<>();
        for (int i = 0; i < input.length; i++) {
            String s = input[i];
            if (isNumber(s))  //如果是數(shù)字拗军,則入棧
                stack.push(Integer.valueOf(s));
            else {
                //遇到運算符任洞,則從棧中彈出兩個數(shù)字,進行運算
                int n1 = stack.pop();
                int n2 = stack.pop();
                int res = 0;
                switch (s){
                    case "+":res = n1 + n2;break;
                    case "-":res = n2 - n1;break;
                    case "*":res = n1 * n2;break;
                    case "/":res = n2 / n1;break;
                }
                stack.push(res);
            }
        }

        return stack.pop();
    }

    /**
     * 將中綴表達式轉化為后綴表達式
     * @param string 9 + ( 3 - 1 ) * 3 + 10 / 2
     * @return
     */
    public static String Calculation2(String string){
        Stack<String> stack = new Stack();
        String[] chars = string.split(" ");
        String res = "";
        for (int i = 0; i < chars.length; i++) {
            String s = String.valueOf(chars[i]);
            if (isNumber(s)){
                if (res.length()==0)
                    res += s;
                else
                    res += " "+s;
            }else {
                if (s.equals("(")){
                    stack.push(s);
                }else {
                    if (s.equals(")")){
                        String t = "";
                        String s1 = "";
                        while (!(t = stack.pop()).equals("(")){
                             s1 += " "+t;
                        }
                        res += s1;
                    }else {
                        int priority = getPriority(s);
                        String s1 = "";
                        boolean flag = false;
                        while (!stack.empty()){
                            flag = false;
                            s1 = stack.pop();
                            if (s1.equals("(")){
//                                stack.push("(");
                                break;
                            }

                            if (getPriority(s1) >= priority){
                                res += " " + s1;
                                flag = true;
                            }
                        }
                        if (!s1.equals("") && !flag)
                            stack.push(s1);
                        stack.push(s);
                    }
                }


            }

        }

        while (!stack.empty()){
            res += " " + stack.pop();
        }


        return res;
    }


    //獲取運算符的優(yōu)先級
    public static int getPriority(String s){
        Map<String,Integer> map = new HashMap<>();
        map.put("+",0);
        map.put("-",0);
        map.put("*",1);
        map.put("/",1);
        map.put("(",2);
        map.put(")",2);


        return map.get(s);
    }

    public static boolean isNumber(String c){

        Pattern pattern = Pattern.compile("^(0|[1-9][0-9]*)$");
        Matcher matcher = pattern.matcher(c);
        boolean res = matcher.find();
        return res;
    }
}

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末发侵,一起剝皮案震驚了整個濱河市交掏,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌刃鳄,老刑警劉巖盅弛,帶你破解...
    沈念sama閱讀 211,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異铲汪,居然都是意外死亡熊尉,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,347評論 3 385
  • 文/潘曉璐 我一進店門掌腰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來狰住,“玉大人,你說我怎么就攤上這事齿梁〈咧玻” “怎么了肮蛹?”我有些...
    開封第一講書人閱讀 157,435評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長创南。 經(jīng)常有香客問我伦忠,道長,這世上最難降的妖魔是什么稿辙? 我笑而不...
    開封第一講書人閱讀 56,509評論 1 284
  • 正文 為了忘掉前任昆码,我火速辦了婚禮,結果婚禮上邻储,老公的妹妹穿的比我還像新娘赋咽。我一直安慰自己,他們只是感情好吨娜,可當我...
    茶點故事閱讀 65,611評論 6 386
  • 文/花漫 我一把揭開白布脓匿。 她就那樣靜靜地躺著,像睡著了一般宦赠。 火紅的嫁衣襯著肌膚如雪陪毡。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,837評論 1 290
  • 那天勾扭,我揣著相機與錄音毡琉,去河邊找鬼。 笑死尺借,一個胖子當著我的面吹牛绊起,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播燎斩,決...
    沈念sama閱讀 38,987評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼虱歪,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了栅表?” 一聲冷哼從身側響起笋鄙,我...
    開封第一講書人閱讀 37,730評論 0 267
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎怪瓶,沒想到半個月后萧落,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,194評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡洗贰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,525評論 2 327
  • 正文 我和宋清朗相戀三年找岖,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片敛滋。...
    茶點故事閱讀 38,664評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡许布,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出绎晃,到底是詐尸還是另有隱情蜜唾,我是刑警寧澤杂曲,帶...
    沈念sama閱讀 34,334評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站袁余,受9級特大地震影響擎勘,放射性物質發(fā)生泄漏。R本人自食惡果不足惜颖榜,卻給世界環(huán)境...
    茶點故事閱讀 39,944評論 3 313
  • 文/蒙蒙 一棚饵、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧掩完,春花似錦蟹地、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,764評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽夺刑。三九已至缅疟,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間遍愿,已是汗流浹背存淫。 一陣腳步聲響...
    開封第一講書人閱讀 31,997評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留沼填,地道東北人桅咆。 一個月前我還...
    沈念sama閱讀 46,389評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像坞笙,于是被迫代替她去往敵國和親岩饼。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,554評論 2 349

推薦閱讀更多精彩內(nèi)容