数据结构 前缀中缀后缀

目录

前言

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

二,前缀与后缀表达式

三,使用栈实现后缀

四,由中缀到后缀

总结


前言

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


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

如何撰写一个表达式?

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

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

操作符的优先级

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里面栈的使用了和计算机是如何计算这个后缀表达式的

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

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

相关文章

笔灵ai写作技术浅析(三):深度学习

笔灵AI写作的深度学习技术主要基于Transformer架构,尤其是GPT(Generative Pre-trained Transformer)系列模型。 1. Transformer架构 Transformer架构由Vaswani等人在2017年提出,是GPT系列模型的基础。它摒弃了传统的循环神经网络(RNN)和卷积神经网络(CNN),完全依赖自…

专业的定制版软件,一键操作,无限使用

今天给大家介绍一个专业的PDF转word的小软件&#xff0c;软件只有5.5M。非常小&#xff0c;而且没有文档大小的限制&#xff0c;可以随意使用。 PDFtu PDF转word 软件第一次使用需要安装一下。 安装好之后&#xff0c;我们就能在桌面找到对应的图标&#xff0c;打开就能直接使…

QGIS系列22-如何提取不规则多边形的中心经纬度

今天我们来学习一下啊如何通过QGIS提取不规则多边形的中心经纬度 1、首先我们把不规则的多边形图形导入进QGIS里面去 2、现在打开的图层是不可以编辑的&#xff0c;因此我们还需要转换成可编辑状态&#xff0c;具体是选择图层&#xff0c;右键点击&#xff0c;选择切换编辑模式…

word2vec 实战应用介绍

Word2Vec 是一种由 Google 在 2013 年推出的重要词嵌入模型,通过将单词映射为低维向量,实现了对自然语言处理任务的高效支持。其核心思想是利用深度学习技术,通过训练大量文本数据,将单词表示为稠密的向量形式,从而捕捉单词之间的语义和语法关系。以下是关于 Word2Vec 实战…

数据库安全管理中的权限控制:保护数据资产的关键措施

title: 数据库安全管理中的权限控制:保护数据资产的关键措施 date: 2025/2/2 updated: 2025/2/2 author: cmdragon excerpt: 在信息化迅速发展的今天,数据库作为关键的数据存储和管理中心,已经成为了企业营运和决策的核心所在。然而,伴随着数据规模的不断扩大和数据价值…

【漫话机器学习系列】076.合页损失函数(Hinge Loss)

Hinge Loss损失函数 Hinge Loss&#xff08;合页损失&#xff09;&#xff0c;也叫做合页损失函数&#xff0c;广泛用于支持向量机&#xff08;SVM&#xff09;等分类模型的训练过程中。它主要用于二分类问题&#xff0c;尤其是支持向量机中的优化目标函数。 定义与公式 对于…

openmv的端口被拆分为两个 导致电脑无法访问openmv文件系统解决办法 openmv USB功能改动 openmv驱动被更改如何修复

我之前误打误撞遇到一次&#xff0c;直接把openmv的全部端口删除卸载然后重新插上就会自动重新装上一个openmv端口修复成功&#xff0c;大家可以先试试不行再用下面的方法 全部卸载再重新插拔openmv 要解决OpenMV IDE中出现的两个端口问题&#xff0c;可以尝试以下步骤&#x…

洛谷P1403 [AHOI2005] 约数研究

题目链接&#xff1a;P1403 [AHOI2005] 约数研究 - 洛谷 | 计算机科学教育新生态 题目难度&#xff1a;普及一 题目分析&#xff1a;本题很明显是要你求从i到n的质因数个数之和&#xff0c;如果采用暴力肯定是超时的&#xff0c;故我的想法是采用埃氏筛法来求时间复杂度为&…

elasticsearch8.15 高可用集群搭建(含认证Kibana)

文章目录 1.资源配置2.系统参数优化3.JDK17安装4.下载&安装ES 8.155.生成ES的证书(用于ES节点之间进行安全数据传输)6.修改ES 相关配置文件7.创建es用户并启动8.配置ES的账号和密码(用于ES服务端和客户端)9.下载和安装Kibana10.编辑Kibana配置文件11.启动Kiabana12.访问Kia…

MATLAB中的IIR滤波器设计

在数字信号处理中&#xff0c;滤波器是消除噪声、提取特征或调整信号频率的核心工具。其中&#xff0c;无限脉冲响应&#xff08;IIR&#xff09;滤波器因其低阶数实现陡峭滚降的特性&#xff0c;被广泛应用于音频处理、通信系统和生物医学工程等领域。借助MATLAB强大的工具箱&…

数据结构:优先级队列—堆

一、优先级队列 1、优先级队列概念 优先级队列&#xff0c;听名字我们就知道他是一种队列&#xff0c;队列在前面我们已经学习过了&#xff0c;它是一种先进先出的数据结构&#xff0c;但是在特殊的情况下&#xff0c;我们我们队列中元素是带有一定优先级的&#xff0c;它需要…

北大:三阶段学习优化多模态推理问答

&#x1f4d6;标题&#xff1a;ReasVQA: Advancing VideoQA with Imperfect Reasoning Process &#x1f310;来源&#xff1a;arXiv, 2501.13536 &#x1f31f;摘要 &#x1f538;视频问答&#xff08;VideoQA&#xff09;是一项具有挑战性的任务&#xff0c;需要理解视频中…

从零开始:用Qt开发一个功能强大的文本编辑器——WPS项目全解析

文章目录 引言项目功能介绍1. **文件操作**2. **文本编辑功能**3. **撤销与重做**4. **剪切、复制与粘贴**5. **文本查找与替换**6. **打印功能**7. **打印预览**8. **设置字体颜色**9. **设置字号**10. **设置字体**11. **左对齐**12. **右对齐**13. **居中对齐**14. **两侧对…

Jason配置环境变量

jason官网 https://jason-lang.github.io/ https://github.com/jason-lang/jason/releases 步骤 安装 Java 21 或更高版本 安装 Visual Studio Code 根据操作系统&#xff0c;请按照以下具体步骤操作 视窗 下载 Jason 的最新版本&#xff0c;选择“jason-bin-3.3.0.zip”…

机器学习--概览

一、机器学习基础概念 1. 定义 机器学习&#xff08;Machine Learning, ML&#xff09;&#xff1a;通过算法让计算机从数据中自动学习规律&#xff0c;并利用学习到的模型进行预测或决策&#xff0c;而无需显式编程。 2. 与编程的区别 传统编程机器学习输入&#xff1a;规…

如何使用SliverGrid组件

文章目录 1 概念介绍2 使用方法3 示例代码 我们在上一章回中介绍了SliverList组件相关的内容&#xff0c;本章回中将介绍SliverGrid组件.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1 概念介绍 我们在本章回中介绍的SliverGrid组件是一种网格类组件&#xff0c;主要用来…

大模型培训讲师老师叶梓分享:DeepSeek多模态大模型janus初探

以下视频内容为叶梓分享DeepSeek多模态大模型janus的部署&#xff0c;并验证其实际效果&#xff0c;包括图生文和文生图两部分。 叶梓老师人工智能培训分享DeepSeek多模态大模型janus初探 DeepSeek 的多模态大模型 Janus 是一款强大的 AI 模型&#xff0c;专注于图像和文本的多…

一文掌握ADB的安装及使用

文章目录 一、什么是ADB&#xff1f;二、 安装ADB2.1 下载ADB2.2 配置环境变量 三、连接Android设备四、 常用ADB命令五、ADB高级功能5.1 屏幕截图和录制5.2 模拟按键输入5.3 文件管理5.4 系统设置管理5.5 系统操作指令5.6 日志操作指令5.7 APK操作指令5.8 设备重启和恢复 六、…

【机器学习与数据挖掘实战】案例11:基于灰色预测和SVR的企业所得税预测分析

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈机器学习与数据挖掘实战 ⌋ ⌋ ⌋ 机器学习是人工智能的一个分支,专注于让计算机系统通过数据学习和改进。它利用统计和计算方法,使模型能够从数据中自动提取特征并做出预测或决策。数据挖掘则是从大型数据集中发现模式、关联…

bat脚本实现自动化漏洞挖掘

bat脚本 BAT脚本是一种批处理文件&#xff0c;可以在Windows操作系统中自动执行一系列命令。它们可以简化许多日常任务&#xff0c;如文件操作、系统配置等。 bat脚本执行命令 echo off#下面写要执行的命令 httpx 自动存活探测 echo off httpx.exe -l url.txt -o 0.txt nu…