数据结构 前缀中缀后缀
目录
前言
一,前缀中缀后缀的基本概念
二,前缀与后缀表达式
三,使用栈实现后缀
四,由中缀到后缀
总结
前言
这里学习前缀中缀后缀为我们学习树和图做准备,这个主题主要是对于算术和逻辑表达式求值,这个还可以用于算法,因为这个可以提高效率,节省时间
一,前缀中缀后缀的基本概念
如何撰写一个表达式?
这个式我们描述一个表达式的过程,这个中间为一个操作符,这个旁边式操作数
就好比如中间的符号就是操作符,旁边的数字就是操作数
操作符的优先级
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 前缀表达式相比中缀表达式就更快一点,不需要考虑优先级问题,效率更高,计算机自行会处理这个表达式
后缀表达式
prefix proefix 2+3 23+ p-q pq-
a+b*c abc*+ 前缀后缀的理解
这里可能会有点懵逼,那我们把这个式子拆开去理解
前缀 后缀 我们不难发现,中缀相对我们容易理解一些,但是效率较低,就是可读性高
前缀和后缀就是可读性差了,但是计算机的效率高
但是为什么还有前缀后缀呢?我们不是要一个就好了吗?其实后缀的效率相比前缀高
后缀表达式:
后缀表达式的计算过程非常直观,从左到右扫描表达式,遇到操作数就压入栈,遇到操作符就从栈中弹出操作数进行计算,然后将结果压入栈。
这种计算方式非常适合计算机实现,因为栈的操作(压栈和弹栈)非常高效,且不需要额外的逻辑来处理操作符优先级。
前缀表达式:
前缀表达式的计算需要从右向左扫描,这在实现上不如从左到右扫描直观。
每次遇到操作符时,需要确定其操作数的范围,这可能需要额外的逻辑来处理嵌套结构,增加了计算复杂度。
所以我们在使用的时候一般都是用后缀表达式,不是用前缀表达式
三,使用栈实现后缀
我们以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)一样逐个提取单词或数字。详细解析:
stringstream是 C++ 标准库中的一个工具,它允许将字符串作为输入流来处理stringstream ss(expr);创建一个stringstream对象ss,并用expr进行初始化- 在
while (ss >> token)这行代码中,ss >> token逐个读取expr中的单词(用空格分隔),存入token变量中这里就是一个流,这里的>>可以理解为从这个流里面取字符提取出来,更cout里<<用法一样的意思,然后识别的到空格或者换行等就会停止当前识别,然后,在继续识别这流里面的字符串,然后用if-else语句来判断是数字和符号这样就可以判断是否为弹出或者压栈
总结我们利用了一个string类型存储这个后缀的字符串,但是要用空格空出对应的数字与符号,然后放入到流里面,用法stringstream 名字(对应的字符串),然后利用操作数来进行编写
前缀也就是同样的写法,这里留给读者自己编写
四,由中缀到后缀
这里直接包含括号,直接一步到位,但是我们先谈谈这个思路
以A+B*C-D*E为例子
这个思路主要是优先级问题,遇到优先级比栈里面小的话就直接弹出来
但是我们由括号呢
这里的代码就先不展示了,后续根据需求写
总结
根据这篇文章我们了解了前缀中缀后缀这些东西,这些东西是可以帮助我们以后再算法里面是追求可读性还是效率作为一个很好的基础,然后我们运用了栈和C++来实现了后缀的实现,这样我们就可以更好掌握stl里面栈的使用了和计算机是如何计算这个后缀表达式的
相关文章:
数据结构 前缀中缀后缀
目录 前言 一,前缀中缀后缀的基本概念 二,前缀与后缀表达式 三,使用栈实现后缀 四,由中缀到后缀 总结 前言 这里学习前缀中缀后缀为我们学习树和图做准备,这个主题主要是对于算术和逻辑表达式求值,这…...
【RocketMQ 存储】- broker 端存储单条消息的逻辑
文章目录 1. 前言2. DefaultMessageStore#asyncPutMessage 添加单条消息2.1 DefaultMessageStore#checkStoreStatus 检查存储服务的状态2.2 DefaultMessageStore#checkMessage 校验消息长度是否合法2.3 CommitLog#asyncPutMessage 核心存储逻辑2.4 MappedFile#appendMessage2.5…...
.Net / C# 分析文件编码 并将 各种编码格式 转为 另一个编码格式 ( 比如: GB2312→UTF-8, UTF-8→GB2312)
相关库 .Net 8 编码识别: github.com/CharsetDetector/UTF-unknown <PackageReference Include"UTF.Unknown" Version"2.5.1" />代码 using UtfUnknown;var dir_path "D:\\Desktop\\新建文件夹2\\新建文件夹"; var dir_new_path &quo…...
Linux文件原生操作
Linux 中一切皆文件,那么 Linux 文件是什么? 在 Linux 中的文件 可以是:传统意义上的有序数据集合,即:文件系统中的物理文件 也可以是:设备,管道,内存。。。(Linux 管理的一切对象…...
(undone) MIT6.S081 2023 学习笔记 (Day7: LAB6 Multithreading)
网页:https://pdos.csail.mit.edu/6.S081/2023/labs/thread.html 任务1:Uthread: switching between threads (moderate) (doing) 在这个练习中,你将设计一个用户级线程系统中的上下文切换机制,并实现它。为了帮助你开始…...
doris:导入时实现数据转换
Doris 在数据导入时提供了强大的数据转换能力,可以简化部分数据处理流程,减少对额外 ETL 工具的依赖。主要支持以下四种转换方式: 列映射:将源数据列映射到目标表的不同列。 列变换:使用函数和表达式对源数据进行实时…...
2021版小程序开发4——基础加强
2021版小程序开发4——基础加强 学习笔记 2025 自定义组件组件中behaviors的作用安装和使用vant-weapp组件库使用MobX实现全局数据共享对小程序的API进行Promise化 具体的内容还包括:使用npm包、全局数据共享、分包和自定义tabBar的案例; 1 自定义组件 …...
Zookeeper入门部署(单点与集群)
本篇文章基于docker方式部署zookeeper集群,请先安装docker 目录 1. docker初期准备 2.启动zookeeper 2.1 单点部署 2.2 集群部署 3. Linux脚本实现快速切换启动关闭 1. docker初期准备 拉取zookeeper镜像 docker pull zookeeper:3.5.6 如果拉取时间过长…...
【AI非常道】二零二五年一月(二),AI非常道
经常在社区看到一些非常有启发或者有收获的话语,但是,往往看过就成为过眼云烟,有时再想去找又找不到。索性,今年开始,看到好的言语,就记录下来,一月一发布,亦供大家参考。 有关AI非…...
jQuery小游戏(二)
jQuery小游戏(二) 今天是新年的第二天,本人在这里祝大家,新年快乐,万事胜意💕 紧接jQuery小游戏(一)的内容,我们开始继续往下咯😜 游戏中使用到的方法 key…...
【硬件测试】基于FPGA的QPSK+帧同步系统开发与硬件片内测试,包含高斯信道,误码统计,可设置SNR
目录 1.算法仿真效果 2.算法涉及理论知识概要 2.1QPSK 2.2 帧同步 3.Verilog核心程序 4.开发板使用说明和如何移植不同的开发板 5.完整算法代码文件获得 1.算法仿真效果 本文是之前写的文章 《基于FPGA的QPSK帧同步系统verilog开发,包含testbench,高斯信道,误码统计,可…...
NVIDIA GPU介绍:概念、序列、核心、A100、H100
概述 入职一家大模型领域创业公司,恶补相关知识。 概念 一些概念: HPC:High Performance Computing,高性能计算SoC:System on Chip,单片系统FLOPS:Floating Point Operations Per Second&am…...
LINUX部署微服务项目步骤
项目简介技术栈 主体技术:SpringCloud,SpringBoot,VUE2, 中间件:RabbitMQ、Redis 创建用户 在linux服务器home下创建用户qshh,用于后续本项目需要的环境进行安装配置 #创建用户 useradd 用户名 #设置登录密…...
C++ list 容器用法
C list 容器用法 C 标准库提供了丰富的功能,其中 <list> 是一个非常重要的容器类,用于存储元素集合,支持双向迭代器。<list> 是 C 标准模板库(STL)中的一个序列容器,它允许在容器的任意位置快速…...
解密全同态加密中的自举(Bootstrapping)
摘要 自举(Bootstrapping)是全同态加密(Fully Homomorphic Encryption, FHE)中经常使用的术语。熟悉 FHE 的人都知道,自举是 FHE 方案中最复杂且计算密集的部分。然而,只有极少数非 FHE 专家真正理解自举操…...
C#方法(练习)
1.定义一个函数,输入三个值,找出三个数中的最小值 2.定义一个函数,输入三个值,找出三个数中的最大值 3.定义一个函数,输入三个值,找出三个数中的平均值 4.定义一个函数,计算一个数的 N 次方 Pow(2, 3)返回8 5.传入十一…...
显示当前绑定变量
来自v$sql中的信息 测试两个变量的情况(实际可以看6个,可根据需要修改) DROP TABLE T1 PURGE; CREATE TABLE T1 AS SELECT A.*,SYSDATE RIQI FROM DBA_USERS A ORDER BY 1;var mc char(3); var id number; exec :mc:SYS; exec :id:50;set li…...
随机森林例子
完整代码: # 导入必要的库 from sklearn.datasets import load_iris from sklearn.ensemble import RandomForestClassifier from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score import numpy as np# 加载鸢尾花数…...
2025年1月个人工作生活总结
本文为 2025年1月工作生活总结。 研发编码 使用sqlite3命令行查询表数据 可以直接使用sqlite3查询数据表,不需进入命令行模式。示例如下: sqlite3 database_name.db "SELECT * FROM table_name;"linux shell使用read超时一例 先前有个编译…...
arm-linux-gnueabihf安装
Linaro Releases windows下打开wsl2中的ubuntu,资源管理器中输入: \\wsl$gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf.tar.xz 复制到/home/ark01/tool 在 Ubuntu 中创建目录: /usr/local/arm,命令如下: …...
vscode和pycharm的区别
VSCode(Visual Studio Code)和 PyCharm 是两款常用的 Python 开发工具,它们在功能和使用体验上有一些关键区别: 1. 核心定位 VSCode:轻量级、多语言支持的代码编辑器,依靠插件扩展 Python 开发能力。PyCh…...
宝塔面板SSL加密访问设置教程
参考:https://www.bt.cn/bbs/thread-117246-1-1.html 如何快速使用证书加密访问面板 因早期默认未开启https访问所以没有相关的风险提醒,现面板默认已开启https加密访问、提升安全性 由于采用的是服务器内部本身签发证书,不被公网浏览器信任请参考以下步…...
Baklib在知识管理创新中的价值体现与其他产品的优势比较分析
内容概要 在当前的数字化时代,知识管理成为企业成功的重要组成部分。有效的知识管理不仅有助于提升内部沟通效率,还能促进创新与决策的科学化。尤其是Baklib作为一种知识中台,具有独特的价值,它能够融合企业内外的知识资源&#…...
Python 数据分析 - 初识 Pandas
Python 数据分析 - 初识 Pandas 简介SeriesDataFrame创建基本操作添加删除 简介 Pandas 基于 NumPy 开发,它提供了快速、灵活、明确的数据结构,旨在简单、直观地处理数据。 Pandas 适用于处理以下类型的数据: 有序和无序的时间序列数据带行…...
力扣【416. 分割等和子集】详细Java题解(背包问题)
首先我们可以求出数组和,当我们找到一个子集中元素的和为数组和的一半时,该就说明可以分割等和子集。 对于该问题我们可以转换成背包问题,求 数组里的元素 装入 数组和的一半大小的背包 能取得的最大值。 然后注意可以剪枝的地方。 代码&…...
机器学习周报-文献阅读
文章目录 摘要Abstract 1 相关知识1.1 WDN建模1.2 掩码操作(Masking Operation) 2 论文内容2.1 WDN信息的数据处理2.2 使用所收集的数据构造模型2.2.1 Gated graph neural network2.2.2 Masking operation2.2.3 Training loss2.2.4 Evaluation metrics 2…...
【Linux】Linux C判断两个IPv6地址是否有包含关系
功能说明 要判断两个 IPv6 地址是否具有包含关系,包括前缀的比较,可以通过以下步骤实现: 解析 IPv6 地址和前缀:将两个 IPv6 地址和它们的前缀长度解析为二进制形式。生成掩码:根据前缀长度生成掩码。按位比较&#…...
【Linux】列出所有连接的 WiFi 网络的密码
【Linux】列出所有连接的 WiFi 网络的密码 终端输入 sudo grep psk /etc/NetworkManager/system-connections/*会列出所有连接过 Wifi 的信息,格式类似 /etc/NetworkManager/system-connections/AAAAA.nmconnection:pskBBBBBAAAAA 是 SSID,BBBBB 是对…...
C语言连接Mysql
目录 C语言连接Mysql下载 mysql 开发库 方法介绍mysql_init()mysql_real_connect()mysql_query()mysql_store_result()mysql_num_fields()mysql_fetch_fields()mysql_fetch_row()mysql_free_result()mysql_close() 完整代码 C语言连接Mysql 下载 mysql 开发库 方法一…...
Synology 群辉NAS安装(6)安装mssql
Synology 群辉NAS安装(6)安装mssql 写在前面mssql 2019:成功安装说明,这个最终成功了 mssql 2022没有成功1. pull image2.启动mssql docker container 远程连接 写在前面 mssq是一个重要节点。 这是因为我对mysql没有一丝好感。虽然接触了许…...







