【CSP考点回顾】后缀表达式计算/中缀表达式转后缀表达式

一、后缀表达式计算

后缀表达式,也被称为逆波兰表示法(Reverse Polish Notation,简称RPN),是一种不需要括号来标识操作符优先级的数学表达式。在后缀表达式中,所有的操作符都跟随在它们的操作数之后,这使得它的结构比标准的算术表达式更为简洁明了,尤其是在进行复杂计算时。其优点主要在于:

  • 消除了表达式中的括号:后缀表达式不需要括号来指定操作的顺序,因为操作符的位置已经明确了操作的顺序。
  • 易于计算机计算:后缀表达式可以很容易地用栈结构在计算机程序中实现,这使得它在编程语言的解释器和编译器中特别有用。
  • 消除了优先级规则的需求:由于计算顺序完全由操作符的位置决定,因此不需要考虑运算符优先级规则。

1.基本结构

后缀表达式的基本规则是:操作数 操作数 操作符。例如,传统算术表达式 3 + 4 3 + 4 3+4 在后缀表达式中表示为 34 + 3 4 + 34+

2.计算方式

要计算后缀表达式的值,需要使用一个栈(Stack):

  1. 从左至右扫描表达式。
  2. 遇到数字时,将其推入栈中。
  3. 遇到操作符时,从栈中弹出两个元素(注意:第一个弹出的元素是右操作数,第二个是左操作数),执行相应的运算,并将结果推回栈中。
  4. 继续执行,直到整个表达式被处理完。
  5. 最后,栈中剩余的元素就是表达式的结果。

3.示例

传统表达式与后缀表达式的对比:

  • 中缀(传统)表达式: ( 3 + 4 ) × 5 (3 + 4) \times 5 (3+4)×5
  • 后缀表达式: 34 + 5 × 3 4 + 5 \times 34+5×

计算过程如下:

  1. 推入3
  2. 推入4
  3. 遇到+操作符,弹出4和3,计算3+4=7,将7推回栈
  4. 推入5
  5. 遇到×操作符,弹出5和7,计算 7 × 5 = 35 7×5=35 7×5=35,将35推回栈

最后,栈中仅剩的数值35就是该后缀表达式的结果。

二、中缀表达式转后缀表达式

中缀表达式是大多数人习惯的数学表达式写法,其中运算符位于两个操作数之间,如 A + B A + B A+B。相比之下,后缀表达式(也称为逆波兰表示法)中,运算符位于操作数之后,例如 A B + A B + AB+
将中缀表达式转换为后缀表达式可以使表达式更易于计算机程序处理,因为后缀表达式不需要括号来指定运算顺序。转换过程通常使用一个栈来辅助.

1.具体步骤:

  1. 创建一个空栈:用于存放运算符(包括括号),以及一个输出列表用于构建后缀表达式。
  2. 从左到右扫描中缀表达式
    • 如果遇到操作数,直接将其添加到输出列表。
    • 如果遇到左括号,将其压入栈中。
    • 如果遇到右括号,则从栈中弹出运算符并添加到输出列表,直到遇到左括号(左括号弹出但不添加到输出列表)。
    • 如果遇到运算符,从栈中弹出所有优先级更高或相等的运算符,并将它们添加到输出列表中,然后将当前运算符压入栈中。
  3. 扫描完成后,从栈中弹出所有剩余的运算符并添加到输出列表

优先级和结合性规则决定了操作符从栈中弹出的时机。在比较运算符优先级时,乘法和除法通常优先于加法和减法。当有多个运算符具有相同的优先级时,它们的结合性决定了它们的

2.示例

将中缀表达式 A * (B + C) / D 转换为后缀表达式:

  1. 扫描 A,因为它是操作数,直接输出 A
  2. 扫描 *,将其压入栈中。
  3. 扫描 (,将其压入栈中。
  4. 扫描 B,因为它是操作数,直接输出 B
  5. 扫描 +,将其压入栈中(注意,尽管 + 的优先级低于 *,但由于 + 在括号内,我们会暂时忽略外部的运算符)。
  6. 扫描 C,因为它是操作数,直接输出 C
  7. 扫描 ),开始弹出栈中的运算符直到遇到 (,因此输出 +,然后丢弃 (
  8. 最后,扫描 /,弹出并输出栈顶的 *(因为 * 的优先级与 / 相等),然后将 / 压入栈。

此时,输出列表为 A B C + ∗ A B C + * ABC+,然后把 / 添加到输出列表(因为栈内不再有其他运算符),所以最终的后缀表达式为 A B C + ∗ / A B C + * / ABC+/

三、代码实现

#include <iostream>
#include <stack>
#include <string>
using namespace std;// 检查字符是否是操作符
bool isOperator(char c) {return c == '+' || c == '-' || c == '*' || c == '/';
}// 检查运算符的优先级
int getPriority(char c) {if (c == '*' || c == '/') return 2;if (c == '+' || c == '-') return 1;return 0;
}// 中缀表达式转后缀表达式
string infixToPostfix(const string& infix) {string postfix;stack<char> opStack;for (char c : infix) {if (c == ' ') continue; // 忽略空格if (isdigit(c)) {postfix += c;}else if (c == '(') {opStack.push(c);}else if (c == ')') {while (!opStack.empty() && opStack.top() != '(') {postfix += opStack.top();opStack.pop();}opStack.pop(); // 弹出 '('}else if (isOperator(c)) {while (!opStack.empty() && getPriority(opStack.top()) >= getPriority(c)) {postfix += opStack.top();opStack.pop();}opStack.push(c);}}// 将栈内剩余的操作符添加到后缀表达式while (!opStack.empty()) {postfix += opStack.top();opStack.pop();}return postfix;
}// 计算后缀表达式
int calculatePostfix(const string& postfix) {stack<int> valStack;for (char c : postfix) {if (isdigit(c)) {valStack.push(c - '0'); // 将字符转换为整数}else {int right = valStack.top(); valStack.pop();int left = valStack.top(); valStack.pop();switch (c) {case '+': valStack.push(left + right); break;case '-': valStack.push(left - right); break;case '*': valStack.push(left * right); break;case '/': valStack.push(left / right); break;}}}return valStack.top();
}int main() {string infix;cout << "Enter infix expression: ";getline(cin, infix); // 读取整行作为中缀表达式string postfix = infixToPostfix(infix);cout << "Postfix expression: " << postfix << endl;int result = calculatePostfix(postfix);cout << "Result: " << result << endl;return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java 错误 java.net.ConnectException

本篇文章介绍了 Java 中的 java.net.ConnectException 错误。 Java 中的 java.net.ConnectException 错误 java.net.ConnectException 是使用网络时最常见的异常。 它主要发生在客户端、应用程序和服务器之间建立 TCP 连接时。 它是一个经过检查的应用程序,可以使用 try-cat…

day2 员工管理 分类管理

文章目录 新增员工RequestBody方法参数注解 接受json数据两个对象之间属性的拷贝MD5加密 新增员工 DTO 用来接收前端传来的参数 vo用于返回数据 pojo和数据库对应 RequestBody方法参数注解 接受json数据 PostMapping("/")public Result save(RequestBody EmployeeD…

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:Rating)

提供在给定范围内选择评分的组件。 说明&#xff1a; 该组件从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 子组件 无 接口 Rating(options?: { rating: number, indicator?: boolean }) 从API version 9开始&#…

pinia和vuex区别?

Pinia 和 Vuex 都是用于 Vue.js 应用状态管理的工具&#xff0c;它们有一些明显的区别&#xff1a; 基于 Vue 3 和 Composition API&#xff1a; Pinia 是为 Vue 3 开发的状态管理库&#xff0c;并且充分利用了 Vue 3 的 Composition API。它提供了一种新的、基于函数的状态管理…

C++从零开始(day49)——AVLTree模拟实现

这是关于一个普通双非本科大一学生的C的学习记录贴 在此前&#xff0c;我学了一点点C语言还有简单的数据结构&#xff0c;如果有小伙伴想和我一起学习的&#xff0c;可以私信我交流分享学习资料 那么开启正题 今天分享的是关于AVLTree模拟实现 1.AVLTree概念 二叉搜索树可…

双场板功率型GaN HEMT中用于精确开关行为的电容建模

来源:Capacitance Modeling in Dual Field-Plate Power GaN HEMT for Accurate Switching Behavior (TED 16年) 摘要 本文提出了一种基于表面电势的紧凑模型&#xff0c;用于描述具有栅极和源极场板&#xff08;FP&#xff09;结构的AlGaN/GaN高电子迁移率晶体管&#xff08;…

嵌入式驱动学习第三周——设备号与字符设备的注册、分配、释放

前言 这一篇博客来谈谈字符设备的注册、分配与释放。 嵌入式驱动学习专栏将详细记录博主学习驱动的详细过程&#xff0c;未来预计四个月将高强度更新本专栏&#xff0c;喜欢的可以关注本博主并订阅本专栏&#xff0c;一起讨论一起学习。现在关注就是老粉啦&#xff01; 目录 前…

盲盒抽卡机小程序——开启神秘之旅!

亲爱的朋友们&#xff0c;欢迎来到盲盒抽卡机小程序&#xff01;这里&#xff0c;是一个充满神秘与惊喜的世界&#xff0c;让你随时随地体验抽卡的乐趣。在这里&#xff0c;你可以轻松尝试各种盲盒&#xff0c;发现隐藏的宝藏&#xff0c;感受心跳加速的刺激。 【丰富多样的盲…

Unity类银河恶魔城学习记录9-4 p92 Death of entity源代码

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili PlayerStat using System.Collections; using System.Collections.Generi…

k8s 安全机制详解

目录 一、安全机制 三个主要安全机制 认证&#xff08;Authentication&#xff09;&#xff1a; 鉴权&#xff08;Authorization&#xff09;&#xff1a; 准入控制&#xff08;Admission Control&#xff09;&#xff1a; 二、 认证 认证方式 对比总结 认证机制框架和相关组件…

小程序学习 1

pages/goods/search/home.wxml首页功能设定 1. loading入场 2. 下拉刷新 3. 搜索栏 4. 分类切换 5. 商品列表 6. 规格弹层 7. 加载更多 <view style"text-align: center; color: #b9b9b9" wx:if"{{pageLoading}}"><t-loading theme"circula…

Java中的常见类“Math”(一)用法详解

Java 中的 Math 类包含了许多数学函数&#xff0c;可以进行各种数学计算。Math 类是 Java 标准库的一部分&#xff0c;不需要额外引入即可使用。它包含在 java.lang 包中&#xff0c;而 java.lang 包中的类会自动导入到每个 Java 源文件中&#xff0c;所以在编写 Java 程序时无…

uView Swiper 轮播图

该组件一般用于导航轮播&#xff0c;广告展示等场景,可开箱即用&#xff0c;具有如下特点&#xff1a; 自定义指示器模式&#xff0c;可配置指示器样式3D轮播图效果&#xff0c;满足不同的开发需求可配置显示标题&#xff0c;涵盖不同的应用场景具有设置加载状态和嵌入视频的能…

月份的天数

目录 题目描述 输入格式 输出格式 输入输出样例 说明/提示 题目描述 输入年份和月份&#xff0c;输出这一年的这一月有多少天。需要考虑闰年。 输入格式 输入两个正整数&#xff0c;分别表示年份 y 和月数 m&#xff0c;以空格隔开。 输出格式 输出一行一个正整数&…

【单调队列】

滑动窗口 给定一个大小为 n≤10^6 的数组。 有一个大小为 k 的滑动窗口&#xff0c;它从数组的最左边移动到最右边。 你只能在窗口中看到 k 个数字。 每次滑动窗口向右移动一个位置。 以下是一个例子&#xff1a; 该数组为 [1 3 -1 -3 5 3 6 7]&#xff0c;k 为 3。 窗口…

利用ffmpeg对两个音频文件进行混音处理

前言 最近&#xff0c;拿到了一个语音识别程序&#xff0c;想测试一下它识别的准确性。原本程序有一段自己的测试音频&#xff0c;准确性还可以&#xff0c;但是&#xff0c;自己想增加一下测试素材的复杂性。想到了在原本的测试音频中引入干扰数据&#xff08;噪点&#xff…

python中的**可以表示什么??

在Python中&#xff0c;** 有两个主要的用途&#xff1a; 作为幂运算符&#xff1a;a ** b 表示a的b次方。例如&#xff0c;2 ** 3 会返回 8&#xff0c;因为2的3次方等于8。 在函数调用或定义时作为关键字参数的解包&#xff1a; 当你有一个字典&#xff0c;并且你想将这个字…

C++从零开始(day44)——二叉搜索树

这是关于一个普通双非本科大一学生的C的学习记录贴 在此前&#xff0c;我学了一点点C语言还有简单的数据结构&#xff0c;如果有小伙伴想和我一起学习的&#xff0c;可以私信我交流分享学习资料 那么开启正题 今天分享的是关于二叉搜索树的知识点 1.二叉搜索树概念 二叉搜…

python+realsense

单目相机(RGB影像):分辨率&#xff1a;320180,320240,424240,640360,640480,848480,960540,1280720,19201080&#xff1b;帧率&#xff1a;6,15,30,60 按照博文Python实战之Realsense_realsense python-CSDN博客的代码显示如下&#xff08;我更改了分辨率和帧率&#xff0c;大…