中缀表达式转后缀表达式

一、基本概念

中缀表达式:运算符都在运算数之间的表达式,也就是我们日常见到的表达式,包含括号。例如:(1+2)*5

后缀表达式:别称逆波兰式,指的是严格从左向右按照运算符出现的顺序进行计算,不包含括号,运算符都放在运算对象的后面的。例如:1 2 + 5 * 就是一个后缀表达式,是由前面中缀表达式的例子转换的。

为什么要转换成后缀表达式?中缀表达式不行吗?

那是因为对于一个中缀表达式 5+8/2 ,我们人可以轻易知道各运算的次序得到答案 9 ,可是计算机不能,计算机很笨,所以需要转换成后缀表达式 5 8 2 / +,这样计算机就能在不考虑各符号优先级的情况下,也得出答案 9(计算机从左向右遍历,将5、8、2入栈,遇到 / ,将8、2出栈,将 8/2 的结果入栈,此时栈中有 5 4 ,遇到 +,将5、4出栈,将 5+4 的结果入栈,遍历完了,栈中有 9,这就是答案。)

 二、中缀表达式转后缀表达式----栈的应用

思路:先从左向右遍历整个中缀表达式

1、如果是运算数:直接输出到后缀表达式

2、遇到左括号 ( :压入栈中,把左括号当做优先级最低的符号

3、遇到右括号 ) :意味着括号中的运算结束了,将运算符一个一个弹出栈顶并且输出到后缀表达式,直到遇到左括号,但是左括号不加入到后缀表达式

4、对于运算符 + - * /:

        1.如果优先级大于栈顶的运算符或者栈为空时,入栈

        2.否则,即优先级小于等于栈顶的运算符,就将栈顶依次弹出到后缀表达式中去,直到满足入栈条件。

( 此时是优先级最低的符号

遍历完中缀表达式后,可能栈中还存有运算符,依次弹出直至栈空。

转换过程分析(以(3+5)*3-2/1为样例,结果是3 5 + 3 * 2 1 / -)

1.遍历到(,入栈
后缀表达式为:
栈中元素:(
2.遍历到3,输出到后缀表达式
后缀表达式为:3
栈中元素:(
3.遍历到+(优先级1),大于栈顶元素(的优先级,入栈
后缀表达式为:3
栈中元素:(+
4.遍历到5,输出到后缀表达式
后缀表达式为:3 5
栈中元素:(+
5.遍历到),一直出栈输出到后缀表达式,直到遇到(,但是(不加入后缀表达式
后缀表达式为:3 5 +
栈中元素:
6.遍历到*,栈为空,入栈
后缀表达式为:3 5 +
栈中元素:*
7.遍历到3,输出到后缀表达式
后缀表达式为:3 5 + 3
栈中元素:*
8.遍历到-,小于等于*的优先级,*出栈输出到后缀表达式,-入栈
后缀表达式为:3 5 + 3 *
栈中元素:-
9.遍历到2,输出到后缀表达式
后缀表达式为:3 5 + 3 * 2
栈中元素:-
10.遍历到/,/的优先级大于-,入栈
后缀表达式为:3 5 + 3 * 2
栈中元素:-/
11.遍历到1,输出到后缀表达式
后缀表达式为:3 5 + 3 * 2 1
栈中元素:-/
12.遍历完了,可是栈未空,出栈直至栈空
后缀表达式为:3 5 + 3 * 2 1 / -
栈中元素: 

至此结束 。

三、代码

转换代码:

int priority(char ch) //返回优先级-优先级越高值越大
{if (ch == '('){return 0;}else if (ch == '+' || ch == '-'){return 1;}else //    * /{return 2;}
}void trans(string arr1, string &arr2)
{Stack stack;initStack(stack);DateElem e = ' '; //用于传出栈中元素for (int i = 0; i < arr1.size(); i++) //每次arr2加入元素后,都加一个空格以分割{if (arr1[i] == ' ') //跳过空格{continue;}if(arr1[i] >= '0' && arr1[i] <= '9') //情况1{while (arr1[i] >= '0' && arr1[i] <= '9'){arr2.push_back(arr1[i]);i++;}arr2.push_back(' ');i--; //因为当不是数字时,i也++了,i等下循环中还要++,所以得--}else if (arr1[i] == '(' ) //情况2{pushStack(stack, arr1[i]);}else if (arr1[i] == ')') //情况3{while (!IsEmpty(stack) && getTop(stack)!='('){popStack(stack, e);arr2.push_back(e);arr2.push_back(' ');}if(getTop(stack) == '(')popStack(stack,e); //将 '(' 弹出栈}else //情况4{while (!IsEmpty(stack) && priority(getTop(stack) ) >=priority( arr1[i] )) //栈不为空 并且 栈顶元素优先级大于等于遍历的字符{popStack(stack, e);arr2.push_back(e);arr2.push_back(' ');}pushStack(stack, arr1[i]); //循环结束,就满足入栈条件,栈为空 或者 优先级小于栈顶元素}}while (!IsEmpty(stack))  //输出栈中剩余的元素{popStack(stack, e);arr2.push_back(e);arr2.push_back(' ');}return;}

全部代码:

#define _CRT_SECURE_NO_WARNINGS 1#include <iostream>
#include <string>using namespace std;//栈的数据结构定义
#define MAX_SIZE 120typedef char DateElem;
typedef struct _Stack
{DateElem* top;DateElem* base;
}Stack;//初始化栈
bool initStack(Stack& s)
{s.base = new DateElem[MAX_SIZE];if (!s.base) return false; //空间分配失败s.top = s.base; //空栈return true;
}//入栈
bool pushStack(Stack& s, DateElem e)
{if (!s.base || (s.top - s.base) >= MAX_SIZE) return false; //栈没建立 或者 栈满了*(s.top++) = e;return true;
}//出栈
bool popStack(Stack& s, DateElem& e)
{if (!s.base || s.base == s.top) return false;e = *(--s.top); //先将栈顶元素赋值给e,栈顶指针再移动,因为栈顶指针都是指向栈顶元素的后一个位置return true;
}//获取栈顶元素
DateElem getTop(Stack& s)
{if (s.top > s.base) //栈不为空{return *(s.top - 1);}else{cout << "栈为空" << endl;return 1;}
}//判断栈是否为空
bool IsEmpty(Stack& s)
{if (s.base == s.top){return true;}else{return false;}}//获取栈中元素的个数
int getLength(Stack& s)
{return (int)(s.top - s.base);
}//销毁栈
void destoryStack(Stack& s)
{//与初始化栈一一对应if (s.base != NULL) //有效{delete s.base;s.base = s.top = NULL;}}int priority(char ch) //返回优先级-优先级越高值越大
{if (ch == '('){return 0;}else if (ch == '+' || ch == '-'){return 1;}else //    * /{return 2;}
}void trans(string arr1, string &arr2)
{Stack stack;initStack(stack);DateElem e = ' '; //用于传出栈中元素for (int i = 0; i < arr1.size(); i++) //每次arr2加入元素后,都加一个空格以分割{if (arr1[i] == ' ') //跳过空格{continue;}if(arr1[i] >= '0' && arr1[i] <= '9') //情况1{while (arr1[i] >= '0' && arr1[i] <= '9'){arr2.push_back(arr1[i]);i++;}arr2.push_back(' ');i--; //因为当不是数字时,i也++了,i等下循环中还要++,所以得--}else if (arr1[i] == '(' ) //情况2{pushStack(stack, arr1[i]);}else if (arr1[i] == ')') //情况3{while (!IsEmpty(stack) && getTop(stack)!='('){popStack(stack, e);arr2.push_back(e);arr2.push_back(' ');}if(getTop(stack) == '(')popStack(stack,e); //将 '(' 弹出栈}else //情况4{while (!IsEmpty(stack) && priority(getTop(stack) ) >=priority( arr1[i] )) //栈不为空 并且 栈顶元素优先级大于等于遍历的字符{popStack(stack, e);arr2.push_back(e);arr2.push_back(' ');}pushStack(stack, arr1[i]); //循环结束,就满足入栈条件,栈为空 或者 优先级小于栈顶元素}}while (!IsEmpty(stack))  //输出栈中剩余的元素{popStack(stack, e);arr2.push_back(e);arr2.push_back(' ');}return;}
int main(void)
{Stack stack;initStack(stack);string arr1 = "";string arr2= "";cout << "请输入中缀表达式:"; //((1+2)*3)-(6-5)getline(cin, arr1);trans(arr1, arr2);cout << "转为后缀表达式为:"; //1 2 + 3 * 6 5 - -cout << arr2 << endl;return 0;
}

其中包括了栈的代码,你也可以使用库中的栈。

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

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

相关文章

【ChatGPT瀑布到水母】AI 在驱动软件研发的革新与实践

这里写目录标题 前言内容简介作者简介专家推荐读者对象目录直播预告 前言 计算机技术的发展和互联网的普及&#xff0c;使信息处理和传输变得更加高效&#xff0c;极大地改变了金融、商业、教育、娱乐等领域的运作方式。数据分析、人工智能和云计算等新兴技术&#xff0c;也在不…

C语言 pthread_create

备注void *&#xff0c;最好添加返回值 原因&#xff1a;在实践中&#xff0c;虽然你的函数可能不需要返回任何值&#xff0c;但为了与 pthread_create 函数的预期函数指针格式相匹配&#xff0c;最好遵守函数指针所需的返回类型。这是一种良好的编程实践&#xff0c;确保你的代…

用起来顺手的在线表结构设计软件工具Itbuilder,与你共享

在线表结构设计软件工具需功能简洁&#xff0c;去除晦涩难懂的设置&#xff0c;化繁为简&#xff0c;实用为上&#xff0c;上手非常容易&#xff0c;这些itbuilder统统可以做到。 itbuilder是一款基于浏览器开发的在线表结构设计软件工具&#xff0c;借助人工智能提高效率&…

玩转视图变量,轻松实现动态可视化数据分析

前言 在当今数据驱动的世界中&#xff0c;数据分析已经成为了企业和组织中不可或缺的一部分。传统的静态数据分析方法往往无法满足快速变化的业务需求和实时决策的要求。为了更好地应对这些挑战&#xff0c;观测云的动态可视化数据分析应运而生。 在动态可视化数据分析中&…

io测试【FPGA】

// module io_def // 模块名字&#xff0c;参数&#xff0c;方法体 (input FPGA_CLK_50M_b5,input key1_k18,input key2_n17,input key3_n18,input key4_h17, //output led1_d15,output led2_c15,output led3_a12,output led4_b12,output beep_h13 //【注】最后一个参数不…

vue3学习(十四)--- vue3中css新特性

文章目录 样式穿透:deep()scoped的原理 插槽选择器:slotted()全局选择器:global()动态绑定CSScss module 样式穿透:deep() 主要是用于修改很多vue常用的组件库&#xff08;element, vant, AntDesigin&#xff09;&#xff0c;虽然配好了样式但是还是需要更改其他的样式就需要用…

3.12每日一题(有理函数不定积分)

两种方法&#xff1a; 1、拆项&#xff0c;然后分别加项减项拆&#xff0c;把分母降幂 注&#xff1a; x凑x的平方时前面要乘1/2 分子为x的平方可以分一个x去凑x的平方 2、联想三角有理函数公式&#xff0c;使用三角函数求解 用tant替换x&#xff1b;再通过二倍角公式降幂即可 …

QT: QLineEdit 密码模式、QLineEdit输入模式

setEchoMode(QLineEdit::Normal) 是一个函数&#xff0c;用于设置 QLineEdit 对象的输入模式。具体用法如下&#xff1a; lineEdit->setEchoMode(QLineEdit::Normal);该函数的作用是将 QLineEdit 对象的输入模式设置为“正常模式”&#xff0c;在此模式下&#xff0c;用户的…

数智领航未来∣2023契约锁企企通专题沙龙:数字建设,为企业高质量发展注入新动能

今年两会期间&#xff0c;“数字经济”是当之无愧的热词之一。中央经济工作会议提出&#xff0c;要大力发展数字经济&#xff0c;提升常态化监管水平&#xff0c;支持平台经济发展。 当前数据作为新型生产要素&#xff0c;价值尚未得到充分释放&#xff0c;需要疏通数据要素流通…

数控 (CNC) 加工设计:​​​​​​​Filou NC Gorilla 2023 Crack

Filou NC Gorilla是一款功能强大的软件&#xff0c;专为计算机数控 (CNC) 加工而设计。它是一款全面且多功能的工具&#xff0c;可让用户轻松创建高精度零件和组件。 专家估计&#xff0c;所有 CNC 零件中 80-90% 是 2.5D 零件。 因此无需创建复杂的 3D 模型&#xff0c;而是可…

CN考研真题知识点二轮归纳(1)

本轮开始更新真题中涉及过的知识点&#xff0c;总共不到20年的真题&#xff0c;大致会出5-10期&#xff0c;尽可能详细的讲解并罗列不重复的知识点~ 目录 1.三类IP地址网络号的取值范围 2.Socket的内容 3.邮件系统中向服务器获取邮件所用到的协议 4.RIP 5.DNS 6.CSMA/CD…

【C++的OpenCV】第十四课-OpenCV基础强化(三):单通道Mat元素的访问之data和step属性

&#x1f389;&#x1f389;&#x1f389; 欢迎来到小白 p i a o 的学习空间&#xff01; \color{red}{欢迎来到小白piao的学习空间&#xff01;} 欢迎来到小白piao的学习空间&#xff01;&#x1f389;&#x1f389;&#x1f389; &#x1f496; C\Python所有的入门技术皆在 我…

golang中快速用melody搭建轻量的websocket服务

在Go中&#xff0c;可以使用gin和melody库来搭建一个轻量级的WebSocket服务。gin是一个流行的Web框架&#xff0c;而melody是一个用于处理WebSocket的库。以下是一个简单的示例代码&#xff0c;演示了如何使用gin和melody搭建WebSocket服务&#xff1a; package mainimport (&…

vmware unbuntu22.04卸载与安装vmtools

​ 卸载命令&#xff1a; sudo apt-get purge open-vm-tools-desktop使用 --auto-remove 选项&#xff08;如果重装最好选这个命令&#xff09; sudo apt-get purge --auto-remove open-vm-tools-desktop安装命令&#xff1a; Ubuntu 22.04 Server: sudo apt install open-…

电源控制系统架构(PCSA)之电源控制框架

安全之安全(security)博客目录导读 PCSA的主要目的是描述SoC系统电源控制集成的标准方法。这种方法的一个关键组成部分是电源控制框架。下图显示了电源控制框架概念的高级说明。 电源控制框架是标准基础设施组件、接口和相关方法的集合&#xff0c;可用于构建SoC电源管理所需的…

小米电视播放win10视频 win10共享问题

解决的方法就是安装SMB1.0协议 重启就OK了

【贝叶斯回归】【第 1 部分】--pyro库应用

Bayesian Regression - Introduction (Part 1) — Pyro Tutorials 1.8.6 documentation 一、说明 我们很熟悉线性回归的问题&#xff0c;然而&#xff0c;一些问题看似不似线性问题&#xff0c;但是&#xff0c;用贝叶斯回归却可以解决。本文使用土地平整度和国家GDP的关系数据…

前端图片上传的处理与后端的接收(c#)

前端上传图片数据 //上传图片的处理方法UpdateHeadSculpture() {let self this;let file $("#FileImg")[0].files[0];let form new FormData();form.append("img", file);form.append(context, example_context);$.ajax({url: /UserInfoMation/UpdateHe…

MVCC面试题总结

MVCC解决的问题 ​   数据库并发场景有三种&#xff0c;分别为&#xff1a; ​   1、读读&#xff1a;不存在任何问题&#xff0c;也不需要并发控制 ​   2、读写&#xff1a;有线程安全问题&#xff0c;可能会造成事务隔离性问题&#xff0c;可能遇到脏读、幻读、不可…

Linux:Docker的介绍(1)

Docker官网 Docker: Accelerated Container Application Developmenthttps://www.docker.com/ docker是什么&#xff1f; 是一种轻量级的‘虚拟机’ 在Linux容器里运行应用的开源工具 Docker 是一个开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个…