栈解决括号匹配和后缀表达式的计算问题

栈解决括号匹配和后缀表达式的计算问题

前言

存储货物或供旅客住宿的地方,可引申为仓库、中转站 。例如我们现在生活中的酒店,在古时候叫客栈,是供旅客休息的地方,旅客可以进客栈休息,休息完毕后就离开客栈。我们把生活中的栈的概念引入到计算机中,就是供数据休息的地方,它是一种数据结构,数据既可以进入到栈中,又可以从栈中出去。

一、栈

栈是一种基于先进后出(FILO)的数据结构,是一种只能在一端进行插入和删除操作的特殊线性表。它按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。我们称数据进入到栈的动作为压栈,数据从栈中出去的动作为弹栈
在这里插入图片描述

二、括号匹配问题

  • 问题描述
    检测括号是否一一对应,一个左括号"(",必须对应一个右括号")",且对应顺序一致。
  • 利用栈解决该问题的思路
    在这里插入图片描述
    在这里插入图片描述
  • Java代码实现
// 利用栈 解决括号是否匹配问题
public class BracketMatch {
    public static void main(String[] args) {
        String s="(mekeater(sun))";
        boolean b = IsMatch(s);
        System.out.println("字符串 "+s +"中的括号是否匹配:"+b);
    }
    
    private static boolean IsMatch(String s)
    {
        //1. 创建栈
        Stack<String> chars = new Stack<>();
        //2. 遍历字符串
        for (int i = 0; i < s.length(); i++) {
            //3. 如果字符为左括号(,则入栈
            String c = s.charAt(i)+"";
            if (c.equals("("))
                chars.push(c);
            //4. 否则判断字符为右括号),若是,则弹栈并判断弹出元素是否为null,若为null则不匹配,否则,继续遍历
            else if(c.equals(")"))
            {
                String pop = chars.pop();
                if (pop==null)
                    return false;
            }
        }
        //5. 遍历完成,判断栈中是否还有元素,若有,则不匹配
        if (chars.size()!=0)
            return false;
        else
            return true;
    }
}

三、后缀表达式计算问题

  • 中缀表达式
    中缀表达式就是我们平常生活中使用的表达式,例如:1+3*2,2-(1+3)等等,中缀表达式的特点是:二元运算符总是置于两个操作数中间。
    中缀表达式是人们最喜欢的表达式方式,因为简单,易懂。但是对于计算机来说就不是这样了,因为中缀表达式的运算顺序不具有规律性。不同的运算符具有不同的优先级,如果计算机执行中缀表达式,需要解析表达式语义,做大量的优先级相关操作。
  • 后缀表达式(逆波兰表达式)
    后缀表达式的特点:运算符总是放在跟它相关的操作数之后。
    在这里插入图片描述
  • 问题描述
    如何解决后缀表示的计算问题,以中缀表达式 6*(12-9)+27/9的计算为例,转换为后缀表达式即是: 6 12 9 - * 27 9 / +
  • 利用栈计算后缀表达式的思路
    在这里插入图片描述
  • Java代码实现
// 利用栈,解决后缀表达式的计算问题
public class PostfixNotation {
    
    public static void main(String[] args) {
        // 中缀表达式 6*(12-9)+27/9, 后缀表达式 6 12 9 - * 27 9 / +
        String[] notation={"6","12","9","-","*","27","9","/","+"};
        int result = calculate(notation);
        System.out.println("后缀表达式计算结果为: " + result);
    }

    private static int calculate(String[] notation)
    {
        //1. 创建栈
        Stack<Integer> stack = new Stack<>();
        //2. 遍历表达式
        for (int i = 0; i < notation.length; i++) {
            String curr = notation[i];
            //3. 如果为操作数,则入栈
            //4. 如果为操作符,则出栈两个元素,并与操作符进行计算,计算结果入栈
            Integer o1;
            Integer o2;
            Integer result;
            switch (curr)
            {
                case "+":
                    o1=stack.pop();
                    o2=stack.pop();
                    result=o2+o1;
                    stack.push(result);
                    break;
                case "-":
                    o1=stack.pop();
                    o2=stack.pop();
                    result=o2-o1;
                    stack.push(result);
                    break;
                case "*":
                    o1=stack.pop();
                    o2=stack.pop();
                    result=o2*o1;
                    stack.push(result);
                    break;
                case "/":
                    o1=stack.pop();
                    o2=stack.pop();
                    result=o2/o1;
                    stack.push(result);
                    break;
                default:
                    stack.push(Integer.parseInt(curr));
                    break;
            }
        }
        //5. 栈中最后一个元素就是后缀表达式的计算结果
        Integer over = stack.pop();
        return over;
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mekeater

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值