后缀表达式

什么是后缀表达式?

在计算机科学和数学领域,表达式求值是一项基本且频繁的任务。我们熟知的中缀表达式(如 7 + 15 ∗ 1 + 4 ∗ 1)直观易读,但在计算机处理时却需要复杂的栈或递归算法来解析。相比之下,后缀表达式(又称为逆波兰表示法)则更为简洁。

后缀表达式是一种将运算符放置在操作数之后的表示法。比如,中缀表达式 5 + 3 ∗ 2 在后缀形式下写作 5 3 2 ∗ + 。在这一表示法中,每个运算符紧跟着它作用的所有操作数,消除了括号的需要,简化了计算规则。

后缀表达式的优点

简化解析:后缀表达式无需考虑运算符优先级和括号,可以直接通过栈实现简单高效的计算。
直接计算:遵循遇到操作数入栈,遇到运算符弹出栈顶两个操作数计算并将结果入栈的原则,直至表达式结束。
易于实现:后缀表达式的算法实现相对简单,减少了编程复杂度

中缀转后缀

  • 我们利用栈将中缀表达式转换为后缀表达式。
  • 遍历中缀表达式,如果遇到数字,直接将其添加到输出队列的末尾。
  • 如果遇到的是左括号 (,直接将其压入操作符栈。
  • 如果遇到的是右括号 ),则不断地从操作符栈顶弹出操作符并加入输出队列,直到遇到左括号 ((左括号不加入输出队列,直接丢弃),这样做的目的是将括号内的表达式处理完毕。
  • 对于其他操作符(如 +-*/),需要与栈顶的操作符比较优先级:
  • 如果栈顶操作符优先级更低或栈为空,则将当前操作符压入栈。
  • 如果当前操作符优先级不低于栈顶操作符(如乘除优先于加减),则持续从栈顶弹出操作符加入输出队列,直到栈顶的操作符优先级低于当前操作符,然后将当前操作符压入栈。
  • 遍历完整个中缀表达式后,如果操作符栈中仍有剩余操作符,将它们全部弹出并加入输出队列。

示例:

假设有一个中缀表达式:3 + 4 * 2 - (10 / 5)

转换过程如下:

遇到 3,输出队列变为 3。

遇到 +,压入操作符栈。

遇到 4,输出队列变为 3 4。

遇到 *,由于 * 的优先级高于 +,将 * 压入栈。

遇到 2,输出队列变为 3 4 2。

遇到 -,此时栈顶为 *,优先级不低于 -,故先弹出 * 加入输出队列,然后将 - 压入栈,输出队列变为 3 4 2 *。

遇到左括号 (,压入栈。

遇到 10,输出队列变为 3 4 2 * 10。

遇到 /,压入栈。

遇到 5,输出队列变为 3 4 2 * 10 5。

遇到右括号 ),弹出栈顶直到左括号,输出队列变为 3 4 2 * 10 5 /。

遍历结束,栈中剩余 -,弹出加入输出队列,最终输出队列为:3 4 2 * 10 5  /  - +。

后缀表达式的运算 

后缀表达式的运算也通过栈进行。方法如下:

  • 左到右扫描后缀表达式:每次遇到一个元素,根据以下规则处理:
  • 如果是操作数(数字),直接将其压入栈顶。例如,遇到数字 5,直接将其压入栈中。
  • 如果是运算符(如 +, -, *, /),从栈顶弹出两个操作数(栈顶元素作为第二个操作数,次栈顶元素作为第一个操作数),对它们进行相应的运算,然后将运算结果压回栈顶。
  • 遍历完整个表达式后,栈顶剩下的唯一元素就是整个后缀表达式的计算结果。

示例:

我们用上面算出的后缀表达式进行演示:3 4 2 * 10 5  /  - +。

遍历后缀表达式

遇到 3,压栈 → 栈:[3]

遇到 4,压栈 → 栈:[3, 4]

遇到 2,压栈 → 栈:[3, 4, 2]

遇到 *(乘法),弹出 2 和 4,计算 4 * 2 = 8,压栈 → 栈:[3, 8]

遇到 10,压栈 → 栈:[3, 8, 10]

遇到 5,压栈 → 栈:[3, 8, 10, 5]

遇到 /(除法),弹出 5 和 10,计算 10 / 5 = 2,压栈 → 栈:[3, 8, 2]

遇到 -(减法),弹出 2 和 8,计算 8 - 2 = 6,压栈 → 栈:[3, 6]

遇到 +(加法),弹出 6 和 3,计算 3 + 6 = 9,压栈 → 栈:[9]

遍历完成,栈中剩下 9,这是后缀表达式 3 4 2 * 10 5 / - + 的计算结果。

代码实现

// 辅助函数确定操作符的优先级
int precedence(char op) 
{
    if (op == '*' || op == '/') return 2;
    if (op == '+' || op == '-') return 1;
    return 0; // 无效操作符的默认优先级
}

// 辅助函数判断字符是否为操作符
bool isOperator(char c) 
{
    return c == '+' || c == '-' || c == '*' || c == '/';
}


std::string infixToPostfix(const std::string& infixExp) 
{
    std::stack<char> operators;
    std::stringstream output;
    for (char c : infixExp) 
    {
        if (isdigit(c)) 
        {
            output << c; // 直接输出数字
        } 
        else if (isOperator(c)) 
        {
            while (!operators.empty() && precedence(operators.top()) >= precedence(c)) 
            {
                output << ' ' << operators.top();
                operators.pop();
            }
            operators.push(c);
        } 
        else if (c == '(') 
        {
            operators.push(c);
        } 
        else if (c == ')') 
        {
            while (!operators.empty() && operators.top() != '(') 
            {
                output << ' ' << operators.top();
                operators.pop();
            }
            if (!operators.empty() && operators.top() == '(')
                operators.pop(); // 弹出左括号,但不输出
        }
    }
    // 处理剩余的操作符
    while (!operators.empty())
    {
        output << ' ' << operators.top();
        operators.pop();
    }
    return output.str();
}

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

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

相关文章

深度学习中的优化算法:选择现有的还是自创?

深度学习中的优化算法 深度学习中的优化算法&#xff1a;选择现有的还是自创&#xff1f;现有优化算法的优势**优点包括**&#xff1a; 开发新的优化算法的考虑**开发新算法的原因**&#xff1a;**开发新算法的风险**&#xff1a; 实用建议结论 深度学习中的优化算法&#xff1…

RabbitMQ 是如何做延迟消息的 ?——Java全栈知识(15)

RabbitMQ 是如何做延迟消息的 &#xff1f; 1、什么是死信&#xff1f; 当一个队列中的消息满足下列情况之一时&#xff0c;可以成为死信&#xff08;dead letter&#xff09;&#xff1a; 消费者使用 basic.reject 或 basic.nack 声明消费失败&#xff0c;并且消息的 reque…

5-在Linux上部署各类软件

1. MySQL 数据库安装部署 1.1 MySQL 5.7 版本在 CentOS 系统安装 注意&#xff1a;安装操作需要 root 权限 MySQL 的安装我们可以通过前面学习的 yum 命令进行。 1.1.1 安装 配置 yum 仓库 # 更新密钥 rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022# 安装Mysql…

rk3588局域网推流

最近无意间看见在网上有使用MediaMtx插件配合ffmpeg在Windows来进行推流&#xff0c;然后在使用其他软件进行拉流显示数据图像的&#xff0c;既然windows都可以使用 &#xff0c;我想linux应该也可以&#xff0c;正好手上也有一块RK3588的开发板&#xff0c;就测试了一下&#…

iOS ------ JSONModel源码

一&#xff0c;JSONModel的基本使用 1&#xff0c;基本使用方法 - (instancetype)initWithDictionary:(NSDictionary *)dict error:(NSError **)err; - (instancetype)initWithData:(NSData *)data error:(NSError **)error; - (instancetype)initWithString:(NSString *)str…

Linux网络-部署YUM仓库及NFS共享服务

目录 一.YUM仓库服务 1.YUM概述 1.1.YUM&#xff08;Yellow dog Updater Modified&#xff09; 2.准备安装源 2.1.软件仓库的提供方式 2.2.RPM软件包的来源 2.3.构建CentOS 7 软件仓库 2.4.在软件仓库中加入非官方RPM包组 3.一键安装软件包的工具&#xff1a; 好处&a…

申请Sectigo证书流程详解

Sectigo&#xff08;前身为Comodo CA&#xff09;&#xff0c;是目前主流SSL证书的一种&#xff0c;目前全球范围内应用度也非常广泛&#xff0c;是目前众多品牌中市场份额最大的一个品牌了&#xff0c;在全球证书市场份额占比约为40%。 其超高的市场份额占比主要还是基于其超…

021、Python+fastapi,第一个Python项目走向第21步:ubuntu 24.04 docker 安装mysql8集群、redis集群(二)

系列文章目录 pythonvue3fastapiai 学习_浪淘沙jkp的博客-CSDN博客https://blog.csdn.net/jiangkp/category_12623996.html 前言 安装redis 我会以三种方式安装&#xff0c;在5月4号修改完成 第一、直接最简单安装&#xff0c;适用于测试环境玩玩 第二、conf配置安装 第三…

【Leetcode 42】 接雨水

基础思路&#xff1a; &#xff08;1&#xff09;需要将问题最小化&#xff0c;首先计算第i个位置最多容纳多少雨水&#xff08;细长的一条水柱&#xff09;&#xff0c;然后求和就是总的雨水量&#xff1b; &#xff08;2&#xff09;第i个位置容纳雨水量 min(左侧最高, 右…

​《MATLAB科研绘图与学术图表绘制从入门到精通》示例:绘制德国每日风能和太阳能产量3D线图

在MATLAB中&#xff0c;要绘制3D线图&#xff0c;可以使用 plot3 函数。 在《MATLAB科研绘图与学术图表绘制从入门到精通》书中通过绘制德国每日风能和太阳能产量3D线图解释了如何在MATLAB中绘制3D线图。 购书地址&#xff1a;https://item.jd.com/14102657.html

牛客热题:单链表排序

&#x1f4df;作者主页&#xff1a;慢热的陕西人 &#x1f334;专栏链接&#xff1a;力扣刷题日记 &#x1f4e3;欢迎各位大佬&#x1f44d;点赞&#x1f525;关注&#x1f693;收藏&#xff0c;&#x1f349;留言 文章目录 牛客热题&#xff1a;单链表排序题目链接方法一&…

【XR806开发板试用】基于MQTT与Cjson库的花式点灯

一、项目介绍 久闻openharmony大名&#xff0c;一直没有机会接触&#xff0c;感谢极术社区和全志社区的这次活动&#xff0c;让我能够了解并上手这个系统。 openhamony 1.1的内核是基于liteos内核系统进行构建的&#xff0c;liteos作为物联网系统&#xff0c;结合xr806小型开…

美团KV存储squirrel和Celler学习

文章目录 美团在KV存储squirrel优化和改进在水平方向1、对Gossip协议进行优化 在垂直扩展方面1、forkless RDB数据复制优化2、使用多线程&#xff0c;充分利用机器的多核能力 在高可用方面 美团持久化kv存储celler优化和改进水平扩展优化1、使用bulkload进行数据导入2、线程模型…

Adobe系列软件安装

双击解压 先运行Creative_Cloud_Set_Up.exe。 完毕后&#xff0c;运行AdobeGenP.exe 先Path&#xff0c;选路径&#xff0c;如 C:\Program Files\Adobe 后Search 最后Patch。 关闭软件&#xff0c;修图&#xff01;

电力能源箱3D可视化:开启智慧能源管理新篇章

随着科技的不断进步&#xff0c;电力能源箱的管理与维护逐渐向着智能化、可视化的方向发展。3D可视化技术的崛起&#xff0c;不仅极大地提升了能源管理的效率&#xff0c;更以其直观、生动的特点&#xff0c;引领着电力能源管理领域迈入了一个全新的时代。 电力能源箱作为电力系…

解决一个朋友的nbcio-boot的mysql数据库问题

1、原先安装mysql5.7数据库&#xff0c;导入我的项目里的带数据有报错信息 原因不明 2、只能建议用docker进行msyql5.7的安装 如下&#xff0c;可以修改成自己需要的信息 docker run -p 3306:3306 --name mastermysql -v /home/mydata/mysql/data:/var/lib/mysql -e MYSQL_R…

为什么感觉没有效果

以前在辅导小儿作业的时候&#xff0c;我会在常用的搜索引擎里去寻找答案&#xff0c;一般情况下都能解决问题。 但是最近一段时间&#xff0c;我发现&#xff0c;搜索引擎搜出来的结果还没有利用短视频搜出来的答案更全面&#xff0c;短视频软件不仅可以显示AI整理出来的答案…

js api part4

其他事件 页面加载事件 外部资源&#xff08;如图片、外联CSS和JavaScript等&#xff09;加载完毕时触发的事件 原因&#xff1a;有些时候需要等页面资源全部处理完了做一些事情&#xff0c;老代码喜欢把 script 写在 head 中&#xff0c;这时候直接找 dom 元素找不到。 事件…

2010-2022年上市公司彭博ESG披露评分、分项得分数据

2010-2022年上市公司彭博ESG披露评分、分项得分数据 1、时间&#xff1a;2010-2022年 2、来源&#xff1a;Bloomberg ESG 指数 3、指标&#xff1a;股票代码、股票简称、年份、ESG披露评分、环境披露评分、社会信息披露评分、治理披露评分 4、范围&#xff1a;上市公司 5、…

OpenNJet:下一代云原生应用引擎

OpenNJet&#xff1a;下一代云原生应用引擎 前言一、技术架构二、新增特性1. 透明流量劫持2. 熔断机制3. 遥测与故障注入 三、Ubuntu 发行版安装 OpentNJet1. 添加gpg 文件2. 添加APT 源3. 安装及启动4. 验证 总结 前言 OpenNJet&#xff0c;是一款基于强大的 NGINX 技术栈构建…