栈的应用--四则运算(中缀与后缀表达式转换)

参考链接
结合原文章,做了一定修改,增加Java源码实现


1. 概述

对于四则运算表达式的计算,是输入数据结构中栈的应用,即重点是中缀表达式转换为后缀表达式


2. 后缀表达式计算

  • 为了解释后缀表达式的好处,我们先来看看,计算机是如何计算后缀表达式的
  • 后缀表达式实例9 3 1 - 3 * + 10 2 / +
  • 计算规则:从左到右遍历表达式的每个数字和符号,遇到数字就进栈,遇到是符号,就将处于栈顶的两个数字出栈,进行计算,然后计算结果进栈,一直到最终获得结果。
  • 计算过程:


    image
    image

    image

    image

3. 中缀表达式转后缀表达式

我们把平时标准的四则运算表达式比如9+(3-1)*3+10/2叫做中缀表达式。
中缀表达式:9+(3-1)*3+10/2转换后缀表达式9 3 1 - 3 * + 10 2 / +

  • 转换规则
  1. 当当前字符为数字时,直接输出;
  2. 当当前字符为(时,将其压栈;
  3. 当当前字符为)时,则弹出堆栈中最上的(之前的所有运算符并输出,然后删除堆栈中的(
  4. 当当前字符为运算符时,则依次弹出堆栈中优先级大于等于当前运算符的(到”(“之前为止),输出,再将当前运算符压栈;
    最后弹出所有栈中的内容输出
  • 转换过程
    image

    image

    image

    image

    image

4. 源代码实现

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))  //如果是数字,则入栈
                stack.push(Integer.valueOf(s));
            else {
                //遇到运算符,则从栈中弹出两个数字,进行运算
                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;
    }


    //获取运算符的优先级
    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;
    }
}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,340评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,762评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,329评论 0 329
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,678评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,583评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,995评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,493评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,145评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,293评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,250评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,267评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,973评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,556评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,648评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,873评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,257评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,809评论 2 339

推荐阅读更多精彩内容