十、从中缀向后缀转换表达式
十、从中缀向后缀转换表达式
文章目录
- 十、从中缀向后缀转换表达式
- 题目描述
- 解题思路
- 上机代码
题目描述
中缀表达式就是我们通常所书写的数学表达式,后缀表达式也称为逆波兰表达式,在编译程序对我们书写的程序中的表达式进行语法检查时,往往就可以通过逆波兰表达式进行。我们所要设计并实现的程序就是将中缀表示的算术表达式转换成后缀表示,例如,将中缀表达式
(A 一 (B*C 十 D) *E) / (F 十 G )
转换为后缀表示为:
ABC*D 十 E * 一 FG十/
**注意:**为了简化编程实现,假定变量名均为单个字母,运算符只有+,-,*,/ 和^(指数运算),可以处理圆括号(),并假定输入的算术表达式正确。
**要求:**使用栈数据结构实现 ,输入的中缀表达式以#号结束
输入:
整数N。表示下面有N个中缀表达式
N个由单个字母、整数和运算符构成的表达式
输出:
N个后缀表达式。
测试输入 | 期待的输出 | 时间限制 | 内存限制 | 额外进程 | |
---|---|---|---|---|---|
测试用例 1 |
1(A-(B*C+D)*E)/(F+G)#
|
ABC*D+E*-FG+/
|
1秒 | 64M | 0 |
测试用例 2 |
2a+b*c-d# a-b*(c+d)#
|
abc*+d- abcd+*-
|
1秒 | 64M | 0 |
解题思路
后缀表达式中不含有括号,且后缀表达式中的操作数顺序和中缀表达式的操作数顺序完全相同,只是运算符的位置改变了。考虑用栈来实现,我们可以设置两个栈,一个 opt
栈用来存放运算符,一个 exp
栈用来存放最后的后缀表达式
在将中缀表达式转换为后缀的时候,遵循的原则是:
- 从左到右依次扫描中缀表达式,如果读到的是操作数,直接存入 exp 栈
- 如果读到的是运算符,则进行判断
- 该运算符是 ’ ( ',则直接存入 opt 栈
- 该运算符是 ’ ) ',则将 opt 栈中对应 ‘(’ 前的所有运算符出栈,存入 exp 栈(这一对括号就可以直接舍弃了)
- 如果该运算符不是括号,则将该运算符和 opt 栈顶运算符做比较
- 优先级大于或等于 opt 栈顶运算符,则直接存入 opt 栈
- 优先级小于 opt 栈顶运算符,则让 opt 栈顶运算符出栈并存入 exp 栈中。如果此时新的栈顶运算符优先级大于等于该运算符,继续让栈顶运算符出栈存入exp栈。最后再将该运算符存入 opt 栈
- 当扫描完成后,opt 栈中还有运算符,则将 opt 所有运算符出栈,存入 exp 栈中
符号的优先级定义如下:
(
优先级为 1+
、-
优先级为 3*
、/
优先级为 3^
优先级为 7)
优先级为 9
对于 测试用例1
的转换过程如下:
扫描字符串 | opt栈 | exp栈 |
---|---|---|
( | ( | 空 |
(A | ( | A |
(A- | (- | A |
(A-( | (-( | A |
(A-(B | (-( | AB |
(A-(B* | (-(* | AB |
(A-(B*C | (-(* | ABC |
(A-(B*C+ | (-(+ | ABC* |
(A-(B*C+D | (-(+ | ABC*D |
(A-(B*C+D) | (- | ABC*D+ |
(A-(B*C+D)*
|
(-* | ABC*D+ |
(A-(B*C+D)*E
|
(-* | ABC*D+E |
(A-(B*C+D)*E)
|
空 |
ABC*D+E*-
|
(A-(B*C+D)*E)/
|
/ |
ABC*D+E*-
|
(A-(B*C+D)*E)/(
|
/( |
ABC*D+E*-
|
(A-(B*C+D)*E)/(F
|
/( |
ABC*D+E*-F
|
(A-(B*C+D)*E)/(F+
|
/(+ |
ABC*D+E*-F
|
(A-(B*C+D)*E)/(F+G
|
/(+ |
ABC*D+E*-FG
|
(A-(B*C+D)*E)/(F+G)
|
/ |
ABC*D+E*-FG+
|
(A-(B*C+D)*E)/(F+G)#
|
空 |
ABC*D+E*-FG+/
|
上机代码
懒得手写 C 的栈了,我就直接使用了 C ++ 封装好的栈
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<stack>
using namespace std;bool JudgeOpt(char a, char b)
{//判断两个运算符优先级int value1 = 0, value2 = 0;switch(a){case '(': value1 = 1;break;case '+': value1 = 3;break;case '-': value1 = 3;break;case '*': value1 = 5;break;case '/': value1 = 5;break;case '^': value1 = 7;break;case ')': value1 = 9;break;}switch(b){case '(': value2 = 1;break;case '+': value2 = 3;break;case '-': value2 = 3;break;case '*': value2 = 5;break;case '/': value2 = 5;break;case '^': value2 = 7;break;case ')': value2 = 9;break;}//优先级a<b则falseif(value1 - value2 < 0)return false;elsereturn true;
}
int main()
{int n = 0;scanf("%d",&n);stack<char> opt,exp;while(n--){//初始化两个栈while(!opt.empty())opt.pop();while(!exp.empty())exp.pop();char str[110];scanf("%s",str);char ch; //用一个ch来表示str[i]//求字符串长度int len = 0;while(str[len]!='\0')len++;//扫描字符串for(int i = 0; i < len; i++){ch = str[i];if(ch == '#') //扫描完毕则退出break;//操作数直接压栈if((ch >= 'a'&& ch <= 'z') || (ch >= 'A'&& ch <= 'Z') || (ch >= '0'&& ch <= '9'))exp.push(ch);else //判断括号{if(ch == '(')//左括号直接压栈opt.push(ch);else if(ch == ')')//右括号则取opt中对应的操作符存入exp中{while(opt.top()!='('){exp.push(opt.top());opt.pop();}opt.pop();//舍弃栈顶的左括号}else //判断运算符{if(opt.empty() || JudgeOpt(ch, opt.top()))//优先级大直接存入{opt.push(ch);}else //优先级小,栈顶元素出栈{exp.push(opt.top());opt.pop();while(!opt.empty())//继续出栈{if(JudgeOpt(opt.top(), ch)){exp.push(opt.top());opt.pop();}elsebreak;}opt.push(ch);//最后ch存入opt}}}}//将opt剩余运算符存入exp中while(!opt.empty()){exp.push(opt.top());opt.pop();}//取出exp的后缀表达式,逆序输出int num = 1;while(!exp.empty()){str[num++]=exp.top();exp.pop();}for(int i = num - 1; i > 0; i--){printf("%c", str[i]);}printf("\n");}return 0;
}
十、从中缀向后缀转换表达式相关推荐
- 中缀向后缀转换表达式
中缀向后缀转换表达式 题目信息 输入 输出 测试样例 解答 总结 题目信息 中缀表达式就是我们通常所书写的数学表达式,后缀表达式也称为逆波兰表达式,在编译程序对我们书写的程序中的表达式进行语法检查时, ...
- 天勤数据结构:前缀、中缀、后缀表达式的转换与计算
第三章 栈和队列 1. 输出队列问题 2. 表达式的转换 - 手工转换 2.1 中缀表达式 转 前缀表达式 2.2 中缀表达式 转 后缀表达式 2.3 后缀表达式 转 中缀表达式 2.4 后缀表达式 ...
- 使用栈解决的一类经典问题:表达式转换及求值;中缀表达式;前缀表达式,后缀表达式,中缀转前缀;中缀转后缀;后缀表达式求值;波兰式,逆波兰式
文章目录 背景知识 表达式转换问题(考研经典) 一:手工转换 (1)中缀转前缀和中缀转后缀 (2)前缀转中缀和后缀转中缀 二:用栈实现表达式转换 (1)中缀转后缀 (2)中缀转前缀 表达式计算问题(使 ...
- 【中缀、后缀表达式(整数)的介绍、转换及运算】
中缀.后缀表达式(整数)的介绍.转换及运算 一.简介 二.中缀表达式转后缀表达式 三.中缀表达式转后缀表达式代码实现 四.中缀表达式计算机求值代码实现 1.首先创建一个栈类 2.测试执行 五.后缀表达 ...
- 数据结构:用栈实现表达式的转换(文字描述+详细步骤示例)——中缀转后缀
中缀转后缀 从左到右扫描这个中缀表达式,如果遇到操作数,就直接写出来:如果遇到运算符,就将其入栈. 入栈之前,首先将当前运算符与栈顶运算符比较优先级,如果当前运算符优先级小于等于栈顶运算符的优先级,则 ...
- 中缀和后缀表达式的转换
可以用中缀式(a+b+c)*d-e来实际分析一下 1.中缀转后缀: 来源:百度百科 1)设定一个符号栈,并把符号'#'压入栈中,并规定#的优先级最低 2)从左往右扫描表达式,如果是字母就直接发送给后缀 ...
- Java数据结构和算法(六)——前缀、中缀、后缀表达式
前面我们介绍了三种数据结构,第一种数组主要用作数据存储,但是后面的两种栈和队列我们说主要作为程序功能实现的辅助工具,其中在介绍栈时我们知道栈可以用来做单词逆序,匹配关键字符等等,那它还有别的什么功能吗 ...
- 数据结构 - 栈 (逆波兰计算器)(栈的三种表达式)(前缀、中缀和后缀表达式,后缀也叫逆波兰表达式)(中缀表达式转后缀表达式实现步骤及完整代码)
栈的三种表达式:前缀.中缀和后缀表达式,后缀也叫逆波兰表达式 前缀(波兰表达式) 中缀(对人来讲很好理解,对于计算机来讲就方便了,一般会把中缀表达式转换成后缀表达式) 后缀(逆波兰表达式) 计算过程 ...
- (王道408考研数据结构)第三章栈和队列-第三节1:栈的应用之括号匹配问题和表达式问题(前缀、中缀和后缀)
前面我们就说过,栈是一种先进后出的线性表,这种先进后出的特性就决定了它在一类场合或问题中会经常被用到--递归.考研数据结构中所涉及的利用栈结构解决递归问题或者考察栈结构特性的问题主要有这么几类 括号匹 ...
最新文章
- Numpy 统计变量(平均值、标准差、方差、最大、最小、和、乘积、对角线和)
- 并发编程(一)__volatile关键字
- 密码技术应用--SM4文件加解密
- 数据结构(十八)树的定义与存储结构
- linux桌面下安装pptp,Linux下安装PPTP客户端
- POJ-2152 Fire (树形DP)
- Hadoop快速入门——第一章、认识Hadoop与创建伪分布式模式
- 工业自动化控制软件SCADA数据模型的使用方法实例
- python分析鸢尾花数据_iris鸢尾花数据集最全数据分析
- OSN3500 华为SDH全新板卡备件升级扩容
- dede 表单必填_织梦给自定义表单增加必填功能,织梦表单必填设置
- python求向量夹角
- 现代软件工程讲义 7 分析和设计方法
- STM32F103C8T6 点亮LED灯
- (软件工程)-- 总体设计报告
- 使用记账软件记录生活收支明细,如何防止收支不被他人修改
- windows下WNMP(windows+nginx+mysql+php)配置
- halcon初识region
- 汉语中的26种结构歧义
- 高德地图根据经纬度调用api报错Uncaught Error: USERKEY_PLAT_NOMATCH(10009)
热门文章
- 10张图带你深入理解Docker容器和镜像
- 图的遍历:BFS和DFS
- 沈阳大学计算机系教师,张春芳(信息工程学院)老师 - 沈阳大学 - 院校大全
- python线程代码_python--(十步代码学会线程)
- xmlstreamexception 参数实体未进行声明_命名实体识别研究进展概述
- 100路监控摄像头需要使用核心交换机吗?
- 数据中心2022:绿色的下一步是智能化
- DL之ResNet:ResNet算法的简介(论文介绍)、架构详解、案例应用等配图集合之详细攻略
- DL之RNN:基于TF利用RNN实现简单的序列数据类型(DIY序列数据集)的二分类(线性序列随机序列)
- ML之SVM:基于sklearn的svm算法实现对支持向量的数据进行标注