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

数据结构 前缀中缀后缀

目录

前言

一,前缀中缀后缀的基本概念

二,前缀与后缀表达式

三,使用栈实现后缀

四,由中缀到后缀

总结


前言

这里学习前缀中缀后缀为我们学习树和图做准备,这个主题主要是对于算术和逻辑表达式求值,这个还可以用于算法,因为这个可以提高效率,节省时间


一,前缀中缀后缀的基本概念

如何撰写一个表达式?

这个式我们描述一个表达式的过程,这个中间为一个操作符,这个旁边式操作数

就好比如中间的符号就是操作符,旁边的数字就是操作数

操作符的优先级

1,括号(( )  { }  [ ])

2,幂运算,如果是2^5^6,这个是先从最右边运算,把5的6次方算出来,然后再计算2的3125次方

3,乘除法,(从左到右)

4,加减法,(从左到右)

中缀表达式:1,先看优先级  2,再看同优先级的操作符之间的冲突  3,再来看结合律

但是中缀表达式就是需要括号来规定有限级顺序,要不然有时候会得不到自己想要的答案,很容易犯优先级错误,而且因为加了括号,计算机程序需要考虑有限级的问题,会使计算机效率下降,所以还有不考虑优先级顺序的,这个就是前缀表达式和后缀表达式

二,前缀与后缀表达式

前缀表达式:prefix                中缀表达式:infix                后缀表达式:profix 

前缀表达式

infix prefix  
2+3+23
p-q-pq
a+b*c+a*bc

前缀表达式相比中缀表达式就更快一点,不需要考虑优先级问题,效率更高,计算机自行会处理这个表达式

后缀表达式 

prefixproefix
2+323+
p-q

pq-

a+b*cabc*+

前缀后缀的理解

这里可能会有点懵逼,那我们把这个式子拆开去理解

前缀后缀

我们不难发现,中缀相对我们容易理解一些,但是效率较低,就是可读性高

                         前缀和后缀就是可读性差了,但是计算机的效率高

但是为什么还有前缀后缀呢?我们不是要一个就好了吗?其实后缀的效率相比前缀高

  • 后缀表达式

    • 后缀表达式的计算过程非常直观,从左到右扫描表达式,遇到操作数就压入栈,遇到操作符就从栈中弹出操作数进行计算,然后将结果压入栈。

    • 这种计算方式非常适合计算机实现,因为栈的操作(压栈和弹栈)非常高效,且不需要额外的逻辑来处理操作符优先级。

  • 前缀表达式

    • 前缀表达式的计算需要从右向左扫描,这在实现上不如从左到右扫描直观。

    • 每次遇到操作符时,需要确定其操作数的范围,这可能需要额外的逻辑来处理嵌套结构,增加了计算复杂度。

所以我们在使用的时候一般都是用后缀表达式,不是用前缀表达式

三,使用栈实现后缀

我们以23*54*+9-为例子来写写后缀的程序

思路:

第一代代码实现

#include <iostream>
#include <stack>
#include <string>
/*提供string类型提供length()计算字符串长度提供stoi()函数是把字符串的数字展示出来,其他弄掉
*/
#include <sstream>
#include <cctype>    
/*提供isdigit函数 检查是否为字符*/using namespace std;// 函数用于从字符串中提取操作数
int getOperand(const string& expr, int& index) {string operand;while (index < expr.length() && isdigit(expr[index])) {operand += expr[index++];}return stoi(operand);
}// 函数用于计算后缀表达式的值
int evaluatePostfix(const string& expr) {stack<int>s;int index = 0;while (index < expr.length()) {if (isdigit(expr[index])) {// 如果是操作数,压入栈中s.push(getOperand(expr, index));}else {// 如果是操作符,弹出两个操作数进行计算int operand2 = s.top();s.pop();int operand1 = s.top();s.pop();switch (expr[index]) {case '+': s.push(operand1 + operand2); break;case '-': s.push(operand1 - operand2); break;case '*': s.push(operand1 * operand2); break;case '/': s.push(operand1 / operand2); break;}}index++;}// 栈顶元素即为最终结果return s.top();
}int main() {string postfixExpr = "23*54*+";cout << "后缀表达式的计算结果为: " << evaluatePostfix(postfixExpr) << endl;return 0;
}

我们执行这个代码的时候运行这个23*54*+的结果为77,运行结果是错的,为什么呢,我们通过监视来看看怎么回事

我们会发现这个是把23和54压进去了,然后把23和54进行相加,所以实现错了,这里是需要我们逐个逐个输入到栈里面,而不是一次性输入

string库函数

提供string类型
提供length()计算字符串长度
提供stoi()函数是把字符串的数字展示出来,其他弄掉

(小技巧,这里可以利用s.c来监视这个栈里面的各个值,因为这个是底层容器,这里细讲就涉及的比较多了,等作者学完stl库,然后也会发文章讲述) 

所以目前的问题是解决这个逐个输入的问题

第二代代码

#include <iostream>
#include <stack>
#include <sstream>
#include <string>using namespace std;int evaluatePostfix(const string& expr) {stack<int> s;stringstream ss(expr);  //这个就是为一个类似cin作用的类型string token;while (ss >> token) {if (isdigit(token[0])) {s.push(stoi(token));  // 读取完整的数字}else {int operand2 = s.top(); s.pop();int operand1 = s.top(); s.pop();switch (token[0]) {case '+': s.push(operand1 + operand2); break;case '-': s.push(operand1 - operand2); break;case '*': s.push(operand1 * operand2); break;case '/': s.push(operand1 / operand2); break;}}}return s.top();
}int main() {string postfixExpr = "2 3 * 5 4 * +";  // 需要空格分隔cout << "后缀表达式的计算结果为: " << evaluatePostfix(postfixExpr) << endl;return 0;
}

这里我们就是要输入的时候要注意空格的输入

stringstream ss(expr); 这一行的作用是使用 stringstream 来解析字符串 expr,使其能够像读取输入流(cin)一样逐个提取单词或数字。

详细解析:

  1. stringstream 是 C++ 标准库中的一个工具,它允许将字符串作为输入流来处理
  2. stringstream ss(expr); 创建一个 stringstream 对象 ss,并用 expr 进行初始化
  3. while (ss >> token) 这行代码中,ss >> token 逐个读取 expr 中的单词(用空格分隔),存入 token 变量中

这里就是一个流,这里的>>可以理解为从这个流里面取字符提取出来,更cout里<<用法一样的意思,然后识别的到空格或者换行等就会停止当前识别,然后,在继续识别这流里面的字符串,然后用if-else语句来判断是数字和符号这样就可以判断是否为弹出或者压栈

总结我们利用了一个string类型存储这个后缀的字符串,但是要用空格空出对应的数字与符号,然后放入到流里面,用法stringstream 名字(对应的字符串),然后利用操作数来进行编写

前缀也就是同样的写法,这里留给读者自己编写

四,由中缀到后缀

这里直接包含括号,直接一步到位,但是我们先谈谈这个思路

以A+B*C-D*E为例子

这个思路主要是优先级问题,遇到优先级比栈里面小的话就直接弹出来

但是我们由括号呢 

这里的代码就先不展示了,后续根据需求写 


总结

根据这篇文章我们了解了前缀中缀后缀这些东西,这些东西是可以帮助我们以后再算法里面是追求可读性还是效率作为一个很好的基础,然后我们运用了栈和C++来实现了后缀的实现,这样我们就可以更好掌握stl里面栈的使用了和计算机是如何计算这个后缀表达式的

相关文章:

数据结构 前缀中缀后缀

目录 前言 一&#xff0c;前缀中缀后缀的基本概念 二&#xff0c;前缀与后缀表达式 三&#xff0c;使用栈实现后缀 四&#xff0c;由中缀到后缀 总结 前言 这里学习前缀中缀后缀为我们学习树和图做准备&#xff0c;这个主题主要是对于算术和逻辑表达式求值&#xff0c;这…...

【cocos官方案例改】跳跃牢猫

自制游戏【跳跃牢烟】 案例解析 案例需求&#xff0c;点击鼠标控制白块左右。 资源管理器部分 在body创建一个2d精灵用作玩家。 在地下在创建一个2d精灵用来代表地面。 在body下挂在脚本。 全部脚本如下 &#xff08;在二次进行复刻时候&#xff0c;发现把代码复制上去无法…...

基于Python的药物相互作用预测模型AI构建与优化(上.文字部分)

一、引言 1.1 研究背景与意义 在临床用药过程中,药物相互作用(Drug - Drug Interaction, DDI)是一个不可忽视的重要问题。当患者同时服用两种或两种以上药物时,药物之间可能会发生相互作用,从而改变药物的疗效、增加不良反应的发生风险,甚至危及患者的生命安全。例如,…...

Day51:type()函数

在 Python 中&#xff0c;type() 是一个内置函数&#xff0c;用于返回对象的类型。它可以用于检查变量的类型&#xff0c;也可以用于动态创建新的类型。今天&#xff0c;我们将深入了解 type() 函数的使用方法。 1. 使用 type() 获取变量的类型 最常见的使用方式是将一个对象…...

因果推断与机器学习—用机器学习解决因果推断问题

Judea Pearl 将当前备受瞩目的机器学习研究戏谑地称为“仅限于曲线拟合”,然而,曲线拟合的实现绝非易事。机器学习模型在图像识别、语音识别、自然语言处理、蛋白质分子结构预测以及搜索推荐等多个领域均展现出显著的应用效果。 在因果推断任务中,在完成因果效应识别之后,需…...

计算机网络一点事(21)

第四章 网络层 功能&#xff1a;服务传输层&#xff0c;封装ip数据报&#xff08;主机到主机&#xff09; IP地址以32b表示&#xff0c;以8b为一组记十进制数 异构网络互连&#xff1a;网络结构&#xff0c;主机类型不同 路由器相互配合出IP数据报生成表&#xff0c;根据表…...

springboot使用rabbitmq

使用springboot创建rabbitMQ的链接。 整个项目结构如下&#xff1a; 1.maven依赖 <dependency><groupId>com.rabbitmq</groupId><artifactId>amqp-client</artifactId><version>3.4.1</version> </dependency>application.y…...

【微服务与分布式实践】探索 Eureka

服务注册中心 心跳检测机制&#xff1a;剔除失效服务自我保护机制 统计心跳失败的比例在15分钟之内是否低于85%&#xff0c;如果出现低于的情况&#xff0c;Eureka Server会将当前的实例注册信息保护起来&#xff0c;让这些实例不会过期。当节点在短时间内丢失过多的心跳时&am…...

Day48:获取字典键的值

在 Python 中&#xff0c;字典是一种无序的集合类型&#xff0c;它以键-值对的形式存储数据。字典的每个元素都有一个唯一的键&#xff0c;并且每个键都对应一个值。获取字典中的值是字典操作的常见任务&#xff0c;今天我们将学习如何从字典中获取键对应的值。 1. 使用方括号…...

Java锁自定义实现到aqs的理解

专栏系列文章地址&#xff1a;https://blog.csdn.net/qq_26437925/article/details/145290162 本文目标&#xff1a; 理解锁&#xff0c;能自定义实现锁通过自定义锁的实现复习Thread和Object的相关方法开始尝试理解Aqs, 这样后续基于Aqs的的各种实现将能更好的理解 目录 锁的…...

仿真设计|基于51单片机的温度与烟雾报警系统

目录 具体实现功能 设计介绍 51单片机简介 资料内容 仿真实现&#xff08;protues8.7&#xff09; 程序&#xff08;Keil5&#xff09; 全部内容 资料获取 具体实现功能 &#xff08;1&#xff09;LCD1602实时监测及显示温度值和烟雾浓度值&#xff1b; &#xff08;2…...

文件读写操作

写入文本文件 #include <iostream> #include <fstream>//ofstream类需要包含的头文件 using namespace std;void test01() {//1、包含头文件 fstream//2、创建流对象ofstream fout;/*3、指定打开方式&#xff1a;1.ios::out、ios::trunc 清除文件内容后打开2.ios:…...

【后端开发】字节跳动青训营Cloudwego脚手架

Cloudwego脚手架使用 cwgo脚手架 cwgo脚手架 安装的命令&#xff1a; GOPROXYhttps://goproxy.cn/,direct go install github.com/cloudwego/cwgolatest依赖thriftgo的安装&#xff1a; go install github.com/cloudwego/thriftgolatest编辑echo.thrift文件用于生成项目&…...

SQL UCASE() 函数详解

SQL UCASE() 函数详解 在SQL中&#xff0c;UCASE() 函数是一个非常有用的字符串处理函数&#xff0c;它可以将字符串中的所有小写字母转换为大写字母。本文将详细介绍UCASE() 函数的用法、语法、示例以及其在实际应用中的优势。 一、UCASE() 函数简介 UCASE() 函数是SQL标准…...

99.23 金融难点通俗解释:小卖部经营比喻PPI(生产者物价指数)vsCPI(消费者物价指数)

目录 0. 承前1. 简述&#xff1a;价格指数对比2. 比喻&#xff1a;两大指数对比2.1 简单对比2.2 生动比喻 3. 实际应用3.1 价格传导现象 4. 总结5. 有趣的对比6. 数据获取实现代码7. 数据可视化实现代码 0. 承前 本文主旨&#xff1a; 本文使用小卖部比喻PPI和CPI&#xff0c;…...

【Elasticsearch】match_bool_prefix 查询 vs match_phrase_prefix 查询

Match Bool Prefix Query vs. Match Phrase Prefix Query 在 Elasticsearch 中&#xff0c;match_bool_prefix 查询和 match_phrase_prefix 查询虽然都支持前缀匹配&#xff0c;但它们的行为和用途有所不同。以下是它们之间的主要区别&#xff1a; 1. match_bool_prefix 查询…...

H. Mad City

题目链接&#xff1a;Problem - H - Codeforces 题目大意&#xff1a;给定一个带环的图&#xff0c; 以及a, b两点 判断再图上不断的移动&#xff0c; b想不与a相遇&#xff0c; a想捉到b, 并且二者只能移动一步。 若b跑不掉 NO 否则YES. 具体题目看链接 输入&#xff1a; …...

【图床配置】PicGO+Gitee方案

【图床配置】PicGOGitee方案 文章目录 【图床配置】PicGOGitee方案为啥要用图床图床是什么配置步骤下载安装PicGoPicGo配置创建Gitee仓库Typora中的设置 为啥要用图床 在Markdown中&#xff0c;图片默认是以路径的形式存在的&#xff0c;类似这样 可以看到这是本地路径&#x…...

《程序人生》工作2年感悟

一些杂七杂八的感悟&#xff1a; 1.把事做好比什么都重要&#xff0c; 先树立量良好的形象&#xff0c;再横向发展。 2.职场就是人情世故&#xff0c;但也不要被人情世故绑架。 3.要常怀感恩的心&#xff0c;要记住帮助过你的人&#xff0c;愿意和你分享的人&#xff0c;有能力…...

当当网近30日热销图书的数据采集与可视化分析(scrapy+openpyxl+matplotlib)

当当网近30日热销图书的数据采集与可视化分析(scrapy+openpyxl+matplotlib) 当当网近30日热销书籍官网写在前面 实验目的:实现当当网近30日热销图书的数据采集与可视化分析。 电脑系统:Windows 使用软件:Visual Studio Code Python版本:python 3.12.4 技术需求:scrapy、…...

RestClient

什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端&#xff0c;它允许HTTP与Elasticsearch 集群通信&#xff0c;而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级&#xff…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取 DMA可以提供外设…...

TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案

一、TRS收益互换的本质与业务逻辑 &#xff08;一&#xff09;概念解析 TRS&#xff08;Total Return Swap&#xff09;收益互换是一种金融衍生工具&#xff0c;指交易双方约定在未来一定期限内&#xff0c;基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解

本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

Linux-07 ubuntu 的 chrome 启动不了

文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了&#xff0c;报错如下四、启动不了&#xff0c;解决如下 总结 问题原因 在应用中可以看到chrome&#xff0c;但是打不开(说明&#xff1a;原来的ubuntu系统出问题了&#xff0c;这个是备用的硬盘&a…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配

目录 一、C 内存的基本概念​ 1.1 内存的物理与逻辑结构​ 1.2 C 程序的内存区域划分​ 二、栈内存分配​ 2.1 栈内存的特点​ 2.2 栈内存分配示例​ 三、堆内存分配​ 3.1 new和delete操作符​ 4.2 内存泄漏与悬空指针问题​ 4.3 new和delete的重载​ 四、智能指针…...

MinIO Docker 部署:仅开放一个端口

MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...

什么是VR全景技术

VR全景技术&#xff0c;全称为虚拟现实全景技术&#xff0c;是通过计算机图像模拟生成三维空间中的虚拟世界&#xff0c;使用户能够在该虚拟世界中进行全方位、无死角的观察和交互的技术。VR全景技术模拟人在真实空间中的视觉体验&#xff0c;结合图文、3D、音视频等多媒体元素…...

pycharm 设置环境出错

pycharm 设置环境出错 pycharm 新建项目&#xff0c;设置虚拟环境&#xff0c;出错 pycharm 出错 Cannot open Local Failed to start [powershell.exe, -NoExit, -ExecutionPolicy, Bypass, -File, C:\Program Files\JetBrains\PyCharm 2024.1.3\plugins\terminal\shell-int…...