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

《剑指 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();
    }
};

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


http://www.kler.cn/a/233729.html

相关文章:

  • 【2024最新】基于springboot+vue的闲一品交易平台lw+ppt
  • Ollama的安装以及大模型下载教程
  • HarmonyOS ArkTS 下拉列表组件
  • 生成模型——PixelRNN与PixelCNN
  • 运行springBlade项目历程
  • 低功耗WTK6900P语音ic方案助力电子烟技术革新 打造个性化吸烟体验
  • 计算机毕业设计 | SSM超市进销存管理系统(附源码)
  • 鸿蒙原生应用再添新丁!央视新闻 入局鸿蒙
  • 24 SEMC相关
  • VSTO打包Word插件WPS也支持
  • Go语言每日一练——链表篇(四)
  • 自动化测试工具
  • WifiConfigStore初始化读取-Android13
  • 8868体育助力西甲皇家马德里俱乐部 帮助球队把握榜首大战
  • Days 27 ElfBoard 板 AltiumDesigner 相同电路快速布局布线
  • 【EEG信号处理】对信号进行模拟生成
  • C++自定义函数详解
  • ChatGLM2-6B模型的win10测试笔记
  • 设计模式-装饰模式 Decorator
  • 单片机学习笔记---蜂鸣器工作原理
  • M1 Mac使用SquareLine-Studio进行LVGL开发
  • 锐捷设备常用命令
  • JVM相关-JVM模型、垃圾回收、JVM调优
  • 解析十六进制雷达数据格式:解析雷达FSPEC数据
  • c语言内存对齐
  • Maui blazor ios 按设备类型设置是否启用safeArea