当前位置: 首页 > news >正文

《剑指 Offer》专项突破版 - 面试题 36 : 详解后缀表达式(C++ 实现)

题目链接:LCR 036. 逆波兰表达式求值 - 力扣(LeetCode)

题目

后缀表达式是一种算术表达式,它的操作符在操作数的后面。输入一个用字符串数组表示的后缀表达式,请输出该后缀表达式的计算结果。假设输入的一定是有效的后缀表达式。例如,后缀表达式 ["2", "1", "3", "*", "+"] 对应的算术表达式是 "2 + 1 * 3",因此输出它的计算结果 5。

分析

后缀表达式又叫逆波兰表达式(Reverse Polish Notation, RPN),是一种将操作符放在操作数后面的算术表达式。通常用的是中缀表达式,即操作符位于两个操作数的中间,如 "2 + 1 * 3"。使用后缀表达式的好处是不需要使用括号。例如,中缀表达式的 "2 + 1 * 3" 和 "(2 + 1) * 3" 不相同。它们的后缀表达式分别为 "213*+" 和 "21+3*"。后缀表达式不使用括号也能无歧义地表达这两个不同的算术表达式。

面试小提示:

后缀表达式对于很多人而言可能是一个比较陌生的概念。应聘者在面试的时候遇到新的概念是很常见的。面试官有时故意提出新概念,用来考查应聘者的学习能力。在面试的时候如果遇到不太熟悉的概念,应聘者一定要先确保自己正确理解了这个概念,再动手做题。如果有不理解的地方,应聘者可以提出自己的疑问让面试官提供详细的信息,然后应聘者再列举几个例子向面试官描述自己的理解。如果面试官确认理解是正确的,应聘者再着手做题也不迟。应聘者一定不要害怕向面试官提出问题。能提出有针对性的问题是学习能力的重要体现,在面试过程中这是一个加分项

下面以 ["2", "1", "3", "*", "+"] 为例,分析后缀表达式的计算过程。从左到右扫描这个数组。首先遇到的是操作数 "2",由于这是后缀表达式,操作符还在后面。不知道操作符就不能做计算,于是先将 "2" 保存到某个数据容器中。接下来的两个还是操作数,"1" 和 "3",由于缺少操作符,因此还是不知道如何计算,只好也将它们先后保存到数据容器中。接下来遇到了一个操作符 "*"。按照后缀表达式的规则,这个操作符对应的操作数是 "1" 和 "3",于是将它们从数据容器中取出来。此时容器中有先后保存的 "2"、"1" 和 "3" 这 3 个操作数,此时取出的是后保存的两个,最先保存的 "2" 仍然留在数据容器中。这看起来是 "后进先出" 的顺序,所以可以考虑用来实现这个数据容器。

由于当前的操作符是 "*",因此将两个操作数 "1" 和 "3" 相乘,得到结果 "3"。这个结果可能会成为后面操作符的操作数,因此仍然将它入栈。最后遇到的是操作符 "+",此时栈中有两个操作数,即 "2" 和 "3",分别将它们出栈,然后计算它们的和,得到 "5",再将结果 "5" 入栈。此时整个后缀表达式已经计算完毕,留在栈中的唯一的操作数 "5" 就是结果

代码实现

class Solution {
public:int evalRPN(vector<string>& tokens) {stack<int> st;for (const string& s : tokens){if (s == "+" || s == "-" || s == "*" || s == "/"){int rightOperand = st.top();  // 右操作数st.pop();int leftOperand = st.top();  // 左操作数st.pop();
​switch (s[0]){case '+':st.push(leftOperand + rightOperand);break;case '-':st.push(leftOperand - rightOperand);break;case '*':st.push(leftOperand * rightOperand);break;case '/':st.push(leftOperand / rightOperand);break;}}else{st.push(stoi(s));}}return st.top();}
};

由于栈中只保存操作数,操作符不需要保存到栈中,因此上述代码创建的是一个整数型栈。上述代码逐一扫描后缀表达式数组中的每个字符串,如果遇到的是一个操作数,则将其入栈;如果遇到的是一个操作符,则两个操作数出栈并执行相应的运算,然后计算结果入栈

相关文章:

  • Android 11 webview webrtc无法使用问题
  • 《Django+React前后端分离项目开发实战:爱计划》 03 理解项目结构
  • 【More Effective C++】条款2:使用C++转型操作符
  • 微服务OAuth 2.1扩展额外信息到JWT并解析(Spring Security 6)
  • 力扣231. 2 的幂(数学,二分查找,位运算)
  • 亚马逊认证考试系列 - 知识点 - LightSail介绍
  • 网络选择流程分析(首选网络类型切换流程)
  • Git中为常用指令配置别名
  • 【漏洞复现】狮子鱼CMS某SQL注入漏洞01
  • 服务器禁用了请求中指定的方法
  • Gateway API 实践之(九)FSM Gateway 的双向 TLS
  • vue3 之 商城项目—详情页
  • 政安晨:示例演绎机器学习中(深度学习)神经网络的数学基础——快速理解核心概念(二){两篇文章讲清楚}
  • 如何使用Python + 百度翻译API 自动大批量免费翻译Excel文件中的外语内容
  • 小程序 自定义组件和生命周期
  • 2017年终总结、随想
  • 2018一半小结一波
  • JS基础之数据类型、对象、原型、原型链、继承
  • js算法-归并排序(merge_sort)
  • Linux快速配置 VIM 实现语法高亮 补全 缩进等功能
  • SQLServer插入数据
  • SQLServer之索引简介
  • vue-cli在webpack的配置文件探究
  • 第13期 DApp 榜单 :来,吃我这波安利
  • 使用阿里云发布分布式网站,开发时候应该注意什么?
  • 手机端车牌号码键盘的vue组件
  • 数据可视化之 Sankey 桑基图的实现
  • 提升用户体验的利器——使用Vue-Occupy实现占位效果
  • 小程序 setData 学问多
  • 与 ConTeXt MkIV 官方文档的接驳
  • 原生js练习题---第五课
  • 智能合约Solidity教程-事件和日志(一)
  • 哈罗单车融资几十亿元,蚂蚁金服与春华资本加持 ...
  • 如何通过报表单元格右键控制报表跳转到不同链接地址 ...
  • #14vue3生成表单并跳转到外部地址的方式
  • #laravel 通过手动安装依赖PHPExcel#
  • #在 README.md 中生成项目目录结构
  • (09)Hive——CTE 公共表达式
  • (175)FPGA门控时钟技术
  • (4)事件处理——(7)简单事件(Simple events)
  • (libusb) usb口自动刷新
  • (阿里巴巴 dubbo,有数据库,可执行 )dubbo zookeeper spring demo
  • (附源码)计算机毕业设计SSM疫情居家隔离服务系统
  • (官网安装) 基于CentOS 7安装MangoDB和MangoDB Shell
  • (终章)[图像识别]13.OpenCV案例 自定义训练集分类器物体检测
  • (轉貼) 資訊相關科系畢業的學生,未來會是什麼樣子?(Misc)
  • .NET Framework与.NET Framework SDK有什么不同?
  • .Net 路由处理厉害了
  • .NET 使用 XPath 来读写 XML 文件
  • .NET/C# 编译期能确定的字符串会在字符串暂存池中不会被 GC 垃圾回收掉
  • ??javascript里的变量问题
  • [AX]AX2012开发新特性-禁止表或者表字段
  • [BZOJ 4034][HAOI2015]T2 [树链剖分]
  • [bzoj1901]: Zju2112 Dynamic Rankings
  • [C/C++]数据结构 循环队列