栈的表达式求值中的应用——逆波兰表达式求值+中缀表达式转后缀表达式

文章目录

  • 1. 逆波兰表达式(后缀表达式)求值
    • 思路讲解
    • AC代码
  • 2. 中缀表达式转后缀表达式
    • 分析
    • 方法总结
  • 3. 中缀表达式求值

1. 逆波兰表达式(后缀表达式)求值

链接: link
在这里插入图片描述

这道题目叫做逆波兰表达式求值,那什么是逆波兰表达式呢
我们可以一起来了解一下:
在这里插入图片描述
结合题目中给的测试用例给大家解释一下:
在这里插入图片描述
我们正常写的表达式,就比如题目中的这个:(2 + 1) * 3
这种写法叫做中缀算术表达式,即运算符写在操作数的中间,但是这种写法计算机是不能直接计算的,因为涉及运算符优先级的问题,比如1+2*3,应该先算*
所以呢,这里就需要我们做一件事情,就是把它变成后缀表达式,其实就是根据优先级对表达式中的运算符排一个序,并且放到对应的操作数后面。
就比如题目中给的这个示例:((2 + 1) * 3)这个表达式对应的后缀表达式就是["2","1","+","3","*"](题中是把它放到一个字符串数组中了)。
即1和2先进行后面的+,得到的结果再和3进行后面的*,得到最终结果。这样就直接从前往后算,不用考虑优先级的问题了。

那现在大家对逆波兰表达式应该有一个大致的了解了。

思路讲解

但是呢,单要解这道题目的话,其实很好搞:

我们只需要借助一个栈就搞定了。
具体怎么做呢?
我们去遍历给的逆波兰表达式对应的字符串数组,如果对应的元素是数字,我们就让该操作数入栈,如果遇到操作符,我们就去取栈顶的前两个元素(并pop掉)进行对应的运算(第一个是右操作数,第二个是左操作数),然后将结果入栈,后续重复上述操作,最终栈里面唯一的那个元素就是要求的结果。
举个栗子:
在这里插入图片描述
遍历tokens,2 1入栈,接着遇到+,取出 1 2相加,得到结果3入栈,后面又是一个3入栈,接着遇到* ,取出3 3相乘,结果9入栈。
最终栈里面唯一的元素9就是结果。

AC代码

在这里插入图片描述

class Solution {
public:
    int evalRPN(vector<string>& tokens) {
        stack<int> st;
        for(auto& str:tokens)
        {
            if(str=="+"||str=="-"||str=="*"||str=="/")
            {
                int right=st.top();
                st.pop();
                int left=st.top();
                st.pop();
                switch(str[0])
                {
                    case '+':
                        st.push(left+right);
                        break;
                    case '-':
                        st.push(left-right);
                        break;
                    case '*':
                        st.push(left*right);
                        break;
                    case '/':
                        st.push(left/right);
                        break;
                }
            }
            else
            {
                st.push(stoi(str));
            }
        }
        return st.top();
    }
};

在这里插入图片描述

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

那现在大家再来思考一个问题:
如果给我们一个中缀表达式,我们如何把它转换成对应的后缀表达式

分析

中缀转后缀呢,也是需要借助一个栈,具体怎么做呢?
比如现在有这样一个中缀表达式1+2*3-4
怎么把它转成后缀呢?
🆗,我们还是从头去遍历这个表达式,如果遇到的是操作数,就输出
在这里插入图片描述
如果遇到的是的是操作符,那这时要分情况进行分析:
如果此时栈为空,就让该操作符进栈;

在这里插入图片描述
在这里插入图片描述
如果遇到的是操作符,且此时栈不为空,则取栈顶的操作符与当前操作符比较,比较啥呢——优先级:
如果比栈顶操作符优先级高,就让该操作符进栈,为什么是进栈而不是拿它进行运算呢?
因为后面有可能还有优先级更高的,所以先进栈。

在这里插入图片描述
那进栈之后呢?继续取下一个进行判断是操作数还是操作符。
在这里插入图片描述
如果比栈顶操作符优先级低或者相等,则出栈顶的操作符输出(即此时栈顶的这个操作符可以进行运算了)
在这里插入图片描述
然后再去判断栈是否为空,不为空再拿当前操作符和栈顶操作符比较,进行相应操作,为空就入栈。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
遍历结束后,如果栈不为空,将剩余操作符输出。
在这里插入图片描述
此时,就得到对应的后缀表达式了。
在这里插入图片描述

但是,如果是带括号的情况呢?

比如1+2*(4-5)+6/7,怎么处理?
🆗,那如果按照上面的分析,1输出,+入栈,2输出,*的优先级比栈顶的+高,*也入栈,接着遇到了括号,怎么办?
在这里插入图片描述
如果不加括号的话,后面-比*优先级低,那应该让*先出栈运算,但是现在-在括号里面,所以-应该先运算,所以要认为-的优先级更高。
那我们可以怎么处理呢?当然这里的方法可能不止一种,我们可以这样做:
遇到(,我们认为它的优先级很低,但是我们不拿(做比较,直接让它入栈
在这里插入图片描述
然后遇到括号里的-,栈不为空,比较,因为我们说了认为(的优先级很低,所以-也入栈
在这里插入图片描述
那继续往后走遇到)怎么办?
🆗,)呢我们也认为它的优先级很低,但是)我们要拿它去比较,因为我们认为)优先级很低,所以此时栈顶的-是不是就被成功弹出了。
在这里插入图片描述
然后栈不为空继续跟栈顶比,那此时) 就遇到 (了,拿这时怎么做呢?
这时直接把(pop掉,不输出,然后跳过) 继续看下一个,因为后缀表达式优先级都排好了就不需要括号了。

在这里插入图片描述
拿继续往后走遇到+,栈不为空,跟栈顶比,比栈顶优先级低,栈顶操作符*输出,继续栈还不为空,继续比,优先级相等,出栈顶操作符+
在这里插入图片描述
然后栈空了,+入栈
在这里插入图片描述
然后遇到6输出,遇到/优先级比+高,入栈,然后7输出
在这里插入图片描述
就遍历完了,再把剩余操作符输出
在这里插入图片描述
就得出结果后缀表达式了,大家可以验证一下。

在这里插入图片描述
当然处理括号可能有很多种方法,我们这里提供的只是其中一种,而且我们这种方法如果遇到有些极端的情况可能也不一定处理的了,可能还需要加一些特殊处理。
另外我们会发现就是遇到(是不是好像去开了一个新栈,在这个新栈里去处理括号里的这个子表达式,所以如果这样的问题也可以考虑递归去搞,每次遇到(就递归去处理这个子表达式,处理完回去递归调用的地方继续处理后面的。

方法总结

在这里插入图片描述

3. 中缀表达式求值

那大家再来思考一下,如果给一个中缀表达式,我们该如何求它的值呢?

🆗,是不是就是上面两种操作的结合啊。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/591708.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

阿里云API网关 产品的使用笔记

阿里云的产品虽多&#xff0c;还是一如既往的一用一个看不懂&#xff0c;该模块的文档依旧保持“稳定”发挥&#xff0c;磕了半天才全部跑通。 用阿里云API网关的原因是&#xff0c;在Agent中写插件调用API的时候&#xff0c;需要使用Https协议&#xff0c;又嫌搞备案、证书等事…

【ROS学习】noetic环境搭建

ROS学习&#xff1a;环境搭建 在Ubuntu20.04系统中&#xff0c;搭建noetic环境。 官方资料&#xff1a; https://wiki.ros.org/noetic/Installation/Ubuntu 顺序执行以下所有指令 获取软件包 这里使用清华的镜像源&#xff0c;可以在https://wiki.ros.org/noetic/Installat…

办公数据分析利器:Excel与Power Query透视功能

数据分析利器&#xff1a;Excel与Power Query透视功能 Excel透视表和Power Query透视功能是强大的数据分析工具&#xff0c;它们使用户能够从大量数据中提取有意义的信息和趋势&#xff0c;可用于汇总、分析和可视化大量数据。 本文通过示例演示Power Query透视功能的一个小技…

JavaScript基础(四)

逻辑运算符 && 与 : 多个条件同时满足 ΙΙ 或 : 多个条件满足一个 &#xff01; 非 : 否定某个条件 例: <script> //&多个条件同时满足&#xff0c;才返回true //任意一个为false&#xff0c;就返回false var a 10; var b 20; …

主机win10,VMware 装了ubuntu,ubuntu传文件到主机

亲测可用&#xff0c;1分钟搞定&#xff0c;不能用你打死我 使用 FileZilla 工具互传 FileZilla是一款免费的工具&#xff0c;是基于 FTP 协议进行文件互传的&#xff0c;在传输过程中我们的ubuntu是作为服务器&#xff0c; FileZilla 工具则是作为客户端。 1 ubuntu安装 FTP…

typescript 对象数组和函数

typescript 对象数组和函数 对象 在JavaScript中&#xff0c;对象属于非原始类型。对象也是一种符合数组类型&#xff0c;由若干个对象属性构成。对象属性可以是任意数据类型&#xff0c;比如数组&#xff0c;函数或者对象等。当对象属性为函数的时候&#xff0c;称为方法。 …

基于Spring Boot的音乐网站与分享平台设计与实现

基于Spring Boot的音乐网站与分享平台设计与实现 开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/idea 系统部分展示 系统功能界面图&#xff0c;在系统首页可以查看首…

phpMyAdmin增加自定义IP登录教程

phpMyAdmin增加自定义IP登录教程 1、打开phpMyAdmin目录&#xff0c; 在此目录下是否有config.sample.inc.php文件&#xff0c;如果存在&#xff0c;那么将其改名为config.inc.php&#xff08;为避免修改失误所造成的损失&#xff0c;强烈建议先备份config.sample.inc.php文件…

matlab期末知识

1.期末考什么&#xff1f; 1.1 matlab操作界面 &#xff08;1&#xff09;matlab主界面 &#xff08;2&#xff09;命令行窗口 &#xff08;3&#xff09;当前文件夹窗口 &#xff08;4&#xff09;工作区窗口 &#xff08;5&#xff09;命令历史记录窗口 1.2 matlab搜索…

U盘启动树莓派系统操作流程(3B+)

步骤 使用SD Card启动修改树莓派硬件启动方式 已烧写好的SD Card先 config.txt文件最后一行配置 program_usb_boot_mode1 program_usb_boot_timeout1 ## 超时时间加大到5s, 避免硬件USB枚举时过长导致启动超时。 SD Card接入树莓派&#xff0c; 然后上电, 使用指令 vcgencm…

「2024年」前端开发常用工具函数总结 TypeScript

前言 在前端开发中&#xff0c;工具函数是提高代码复用率、保持代码整洁和增加开发效率的关键。使用 TypeScript 编写工具函数不仅可以帮助开发者捕捉到更多的类型错误&#xff0c;还可以提供更清晰的代码注释和更智能的代码补全。下面是一些在 TypeScript 中常用的前端开发工…

搜好货API接口:快速获取商品列表的利器

搜好货商品列表API接口允许开发者根据关键字搜索并获取相关的商品列表数据。接口支持多种参数配置&#xff0c;可以根据需求灵活调整搜索条件和结果返回格式。 点击获取key和secret API接口请求说明 请求地址&#xff1a;https://api.souhaohuo.com/goods/search请求方法&…

Java——认识异常

目录 一.异常的概念与体系结构 1.异常的概念 1.1算术异常 1.2数组越界异常 1.3空指针异常 2.异常的体系结构 3.异常的分类 3.1编译时异常 3.2运行时异常 二.异常的处理 1.防御式编程 1.1LBYL 1.2EAFP&#xff08;核心&#xff09; 2.异常的抛出 3.异常的捕获 3…

主流Text2Image技术学习

DDPM原理 DDPM&#xff08;Denoising Diffusion Probabilistic Models&#xff09;是一种生成模型&#xff0c;它通过模拟数据的扩散过程来生成新的数据样本。 DDPM通过一个随时间增加噪声的扩散过程和一个逐步去除噪声的生成过程来模拟数据分布。其核心在于训练一个去噪声模…

Steam新人下载安装教程分享 迅游一键下载安装steam

Steam平台是Valve公司聘请的BitTorrent协议&#xff08;BT下载&#xff09;发明者Bram Cohen亲自开发设计。国内玩家对于Valve公司的游戏不会陌生&#xff0c;该公司发行的游戏有半条命系列、反恐精英系列、求生之路系列、传送门系列、军团要塞2、Dota2。Steam平台的客户端新增…

使用docker安装redis

使用docker安装redis ①拉取镜像 docker pull redis:6.2.6② 创建容器 docker run -d --name forum-redis --restartalways -p 6379:6379 redis:6.2.6 redis-server --requirepass "dong97"③链接测试 打开Redis Desktop Manager&#xff0c;输入host、port、pas…

开源版本管理系统的搭建一:SVN服务端安装

作者&#xff1a;私语茶馆 1.Windows搭建SVN版本管理系统 点评&#xff1a;SVN本身非常简洁易用&#xff0c;VisualSVN文档支撑非常好&#xff0c;客户端TortoiseSVN非常专业。5星好评。 1.1.SVN概要和组成 背景介绍 Svn是一个开源版本管理系统&#xff0c;由CollabNet公司…

Java Map集合(二)

1. HashMap原理 1.1 HashMap的容量 HashMap中使用数组作为存储元素的桶&#xff0c;对应的内部属性为table&#xff0c;如下图所示。HashMap的内部数组不是在创建HashMap对象时初始化&#xff0c;而是在首次存入元素时进行初始化&#xff0c;以减少对内存的占用。 从源码注释中…

【STM32+HAL】三轴按键PS2摇杆

一、准备工作&#xff1a; 有关CUBEMX的初始化配置&#xff0c;参见我的另一篇blog&#xff1a;【STM32HAL】CUBEMX初始化配置 有关定时器触发ADC模式配置&#xff0c;详见【STM32HAL】ADC采集波形实现 二、所用工具&#xff1a; 1、芯片&#xff1a; STM32F407VET6 2、CUBE…

小蓝本--因式分解(习题1)讲解

这几天要备战期中&#xff0c;下一期可能要等暑假了...... 小升初的压力真是紧扣于头啊&#xff0c;为了分到一个好班&#xff0c;拼了&#xff01; 对了&#xff0c;下一期可能在寒假更&#xff0c;见谅&#xff01; 1分解因式&#xff1a; 公因式&#xff1a; 答案&#xff…
最新文章