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

【C++经典例题】逆波兰表达式求值:栈的经典应用与实现详解

.

💓 博客主页:倔强的石头的CSDN主页
📝Gitee主页:倔强的石头的gitee主页
⏩ 文章专栏:《C++经典例题》
期待您的关注
在这里插入图片描述

文章目录

      • 题目描述
      • 逆波兰表达式基础
        • 1. 什么是逆波兰表达式?
        • 2. 核心计算规则
      • 解题思路与代码实现
        • 1. 为什么用栈?
        • 2. 代码实现解析
        • 3. 关键细节剖析
      • 边界条件与测试用例
        • 1. 边界情况
        • 2. 测试用例验证
      • 总结

题目描述

LeetCode 150. 逆波兰表达式求值
给定一个逆波兰表达式(后缀表达式),计算其对应的算术值。表达式中的操作数和运算符通过字符串数组 tokens 给出,要求返回最终计算结果。

示例
输入:tokens = ["2","1","+","3","*"]
输出:9
解释:(2 + 1) * 3 = 9


逆波兰表达式基础

1. 什么是逆波兰表达式?

逆波兰表达式(Reverse Polish Notation, RPN)是一种数学表示法,其特点是将运算符置于操作数的后面。例如:

  • 中缀表达式 (2 + 1) * 3 → 后缀表达式 ["2","1","+","3","*"]
  • 中缀表达式 4 / (13 + 5) → 后缀表达式 ["4","13","5","+","/"]

逆波兰表达式的优势是无需括号即可明确运算顺序,且适合计算机通过栈结构高效处理。

2. 核心计算规则
  1. 从左到右遍历表达式。
  2. 遇到操作数则压入栈中。
  3. 遇到运算符则弹出栈顶两个元素,按运算符计算后,将结果压回栈中。
  4. 最终栈中唯一的元素即为结果。

解题思路与代码实现

1. 为什么用栈?
  • 后进先出特性:逆波兰表达式的计算顺序天然符合栈的操作逻辑。运算符作用于最近的两个操作数,栈能快速提供这两个数。
  • 时间复杂度:所有元素仅遍历一次,时间复杂度为 O(n),空间复杂度为 O(n)(最坏情况下栈中存储所有操作数)。
2. 代码实现解析
class Solution {
public:int evalRPN(vector<string>& tokens) {stack<int> st;for (const string& s : tokens) { // 遍历每个tokenif (s == "+" || s == "-" || s == "*" || s == "/") {// 弹出右操作数(先弹出的是右)int right = st.top(); st.pop();int left = st.top(); st.pop();// 根据运算符计算并压栈switch (s[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(s));}}return st.top();}
};
3. 关键细节剖析
  1. 操作数顺序问题

    • 在弹栈时,先弹出的是右操作数,后弹出的是左操作数。
    • 例如表达式 ["4","13","5","+","/"],当处理到 / 时,栈顶为 [4, 18],弹出顺序为 right=18left=4,因此实际计算的是 4 / 18 = 0(向零取整)。
  2. 除法截断规则

    • C++中整数除法默认向零取整(如 6 / -4 = -1),与题目要求一致,因此无需额外处理。
  3. 字符串转整数

    • 使用 stoi(s) 将字符串转换为整数,题目保证输入的合法性,无需处理异常。

边界条件与测试用例

1. 边界情况
  • 单操作数:输入 ["42"] → 输出 42
  • 负数与除法:输入 ["6","-4","/"] → 输出 -1
  • 连续运算符:输入 ["3","4","+","2","*"] → 输出 (3+4)*2=14
2. 测试用例验证
输入:["10","6","9","3","+","-11","*","/","*","17","+","5","+"]
输出:22
步骤分解:1. 9+3=12 → 压入122. -11*12=-132 → 压入-1323. 6/-132=0 → 压入04. 10*0=0 → 压入05. 0+17=17 → 压入176. 17+5=22 → 结果为22

总结

逆波兰表达式求值问题通过栈结构高效解决了运算顺序问题,代码简洁且符合直觉。核心要点包括:

  1. 栈的灵活应用:操作数压栈、运算符弹栈计算。
  2. 操作数顺序:先右后左,确保减法和除法正确性。
  3. 语言特性利用:C++的整数除法规则与题目要求一致。

该问题涉及到的细节问题较多,掌握此问题有助于深入理解栈在表达式计算中的经典应用,同时为后续学习编译原理中的语法解析打下基础。

http://www.dtcms.com/a/426920.html

相关文章:

  • mmcv 安装 2025
  • 设计模式(C++)详解——观察者模式(Observer)(2)
  • LeetCode 392 判断子序列
  • 树的存储结构
  • 2025年9月GESP(C++三级):数组清零
  • 怎样查看网站建设时间注册公司需要什么费用
  • Deepoc具身模型外拓板:重塑居家服务机器人的交互革命
  • cpuset v1
  • 2025年9月个人工作生活总结
  • Java SE “JDK1.8新特性”面试清单(含超通俗生活案例与深度理解)
  • 站台建筑资阳网站推广
  • 【论文阅读 | ECCV 2024 | DAMSDet:具有竞争性查询选择与自适应特征融合的动态自适应多光谱检测变换器】
  • 企业网站 三网系统好玩有趣的网站
  • 小程序的页面宽度 设置多少合适??
  • 基于libwebsockets与cJson的ASR Server实时语音识别实现指南
  • golang 写路由的时候要注意
  • EXCEL哪个版本开始支持VSTO-office插件?
  • 盲盒抽卡机小程序的技术挑战与解决方案
  • 全网网站建设推广国外设计网站都有哪些
  • 零基础学AI大模型之LangChain聊天模型多案例实战
  • GPU 网络基础,Part 2(MoE 训练中的网络挑战;什么是前、后端网络;什么是东西向、南北向流量)
  • 【菜狗学聚类】序列嵌入表示、UMAP降维——20250930
  • 网站外链建设的八大基本准则东大桥做网站的公司
  • MySQL进阶知识点(八)---- SQL优化
  • 【C++STL :vector类 (二) 】攻克 C++ Vector 的迭代器失效陷阱:从源码层面详解原理与解决方案
  • C++ string类常用操作
  • 修改网站模板详解如何开网站需要多少钱
  • 浅谈WebSocket
  • 做网站背景wordpress登录样式
  • 自动化通信谜团:耐达讯自动化Modbus RTU如何变身 Profibus连接触摸屏