利用栈实现中缀表达式转后缀表达式
简介
中缀表示法(或中缀记法)是一个通用的算术或逻辑公式表示方法, 操作符是以中缀形式处于操作数的中间(例:3 + 4)。与前缀表达式(例:+ 3 4)或后缀表达式(例:3 4 +)相比,中缀表达式不容易被电脑解析,但仍被许多程序语言使用,因为它符合人们的普遍用法。
逆波兰表示法(Reverse Polish notation,RPN,或逆波兰记法),是一种是由波兰数学家扬·武卡谢维奇1920年引入的数学表达式方式,在逆波兰记法中,所有操作符置于操作数的后面,因此也被称为后缀表示法。逆波兰记法不需要括号来标识操作符的优先级。
目的
将中缀表达式(即标准的表达式)转换为后缀表达式
例如:1+2*3+(4*5+6)*7 转换成 123*+45*6+7*+
转换原则:
当读到一个操作数时,立即将它放到输出中。操作符不立即输出,放入栈中。遇到圆括号也是推入栈中。
如果遇到一个右括号,那么就将栈元素弹出,将符号写出直到遇到一个对应的左括号。但是这个左括号只被弹出,并不输出。
在读到操作符时,如果此时栈顶操作符优先级大于或等于此操作符,弹出栈顶操作符直到发现优先级更低的元素位置。除了处理‘)’的时候,否则决不从栈中移走‘(’。操作符中,‘+’和‘-’优先级最低,‘*’和‘/’优先级中等,‘(’和‘)’最高。
如果读到输入的末尾,将栈元素弹出直到该栈为空,将符号写到输出中。
实例
首先,读入‘1’,并送到输出,然后‘+’被读入并压入栈中。接下来‘2’读入并送到输出,此时状态如下:
栈:+
输出:1 2
接下来读入‘*’,由于优先级比栈顶元素‘+’大(原则3),因此被压入栈中,接着读入‘3’,并送到输出:
栈:+ *
输出:1 2 3
然后读入‘+’,由于此时栈顶元素为‘*’,优先级比‘+’大,因此将‘*’弹出,弹出后原来的‘+’变为栈顶元素,由于‘+’的优先级和当前读入的‘+’优先级相等,因此也被弹出(原则3),最后将读入的‘+’压入栈中,因此状态如下:
栈:+
输出:1 2 3 * +
下一个读入的符号‘(’,由于具有最高优先级,因此将其放入栈中,然后读入‘4’:
栈:+ (
输出: 1 2 3 * + 4
继续读入,此时读入‘*’,除非处理‘)’,否则‘(’绝不会弹出,因此‘*’被压入栈中,接下来读入‘5’:
栈:+ (*
输出:1 2 3 * + 4 5
往后读入的符号是‘+’,将‘*’弹出并输出。然后将‘+’压入栈中,接着读入‘6’:
栈:+ ( +
输出:1 2 3 * + 4 5 * 6
现在读入‘)’,因此弹出栈中元素直到遇到‘(’:
栈:+
输出:1 2 3 * + 4 5 * 6 +
下一个有读入‘*’,被压入栈中,然后读入‘7’:
栈:+ *
输出:1 2 3 * + 4 5 * 6 + 7
现在输入为空,弹出所有栈中元素
栈:空
输出:1 2 3 * + 4 5 * 6 + 7 * +
实现代码
/*利用栈将(中缀表达式)转换成(后缀表达式)e.g.1+2*3+(4*5+6)*7 转换成 123*+45*6+7*+infix(中缀表达式) : 1+2*3+(4*5+6)*7postfix(后缀表达式) : 123*+45*6+7*+
*/
#include <iostream>
#include <string>
#include <stack>
#include <map>
using namespace std;void InfixToPostfix(const string infix, string& postfix)
{stack<char> mark; // 符号栈std::map<char, int> priority; // 符号优先级priority['+'] = 0;priority['-'] = 0;priority['*'] = 1;priority['/'] = 1;int infix_length = infix.size(); // 中缀表达式的字符长度postfix.reserve(infix_length); for(int i = 0; i < infix_length; ++i) {switch(infix[i]) {case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':postfix.push_back(infix[i]);break;case '+':case '-':case '*':case '/':if(!mark.empty()) {char markTop = mark.top();while(markTop != '(' && priority[infix[i]] <= priority[markTop]) {postfix.push_back(markTop);mark.pop();if(mark.empty()) {break;}markTop = mark.top();}}mark.push(infix[i]);break;case '(':if(infix[i - 1] >= '0' && infix[i - 1] <= '9') { // 5(6/2-1) <==> 5*(6/2-1)mark.push('*');}mark.push(infix[i]);break;case ')':{char markTop = mark.top();while(markTop != '(') {postfix.push_back(markTop);mark.pop();markTop = mark.top();}mark.pop();}break;default:break;}}// 剩余的全部出栈while(!mark.empty()) {postfix.push_back(mark.top());mark.pop();}
}int main(int argc, char const *argv[])
{std::string infix = "1+2*3+(4*5+6)*7+(1+2)";std::string postfix;cout << "infix : " << infix << endl;InfixToPostfix(infix, postfix);cout << "postfix : " << postfix << endl; return 0;
}
利用栈实现中缀表达式转后缀表达式相关推荐
- java利用栈求复杂表达式_java中的栈Stack的基本使用和应用(二) ——利用栈计算合法的算术表达,中缀表达式转后缀表达式...
利用栈Stack计算合法的算术表达式 限定的算术表达式求值问题:包含 "+"."-"."*"."/" .正整数和圆括号的 ...
- 数据结构——栈——中缀表达式和后缀表达式
什么是中缀表达式,什么是后缀表达式 我们一般看见的多项式计算都是中缀表达式构成的:1+2*3+4/3 类似这种,为什么说是中缀呢?因为它的计算符号都是在两个数中间的. 那么自然而然的明白了后缀表达式是 ...
- 栈应用(中缀表达式转后缀表达式并计算后缀表达式的值)
[0]README 0.1) 本文旨在总结 中缀表达式转后缀表达式并计算后缀表达式的值 的步骤,并给出源代码实现: 0.2) 本文中涉及到的源代码均为原创,是对中缀转后缀和计算后缀的简单实现,(旨在理 ...
- 数据结构 - 栈 (逆波兰计算器)(栈的三种表达式)(前缀、中缀和后缀表达式,后缀也叫逆波兰表达式)(中缀表达式转后缀表达式实现步骤及完整代码)
栈的三种表达式:前缀.中缀和后缀表达式,后缀也叫逆波兰表达式 前缀(波兰表达式) 中缀(对人来讲很好理解,对于计算机来讲就方便了,一般会把中缀表达式转换成后缀表达式) 后缀(逆波兰表达式) 计算过程 ...
- 使用栈实现中缀表达式转为后缀表达式和后缀表达式的求解
书籍在线网址http://interactivepython.org/runestone/static/pythonds/index.html 中文翻译书籍:https://facert.gitboo ...
- 栈应用:中缀表达式转后缀表达式
网上有很多关于中缀转后缀的文章,很多文章或多或少都有bug,包括一些教学视频,经过本人无数次测试,保证下面的代码运算结果的正确性!前提是你写的中缀表达式是正确的哈,没有做中缀表达式是否正确的的完整性校 ...
- 数据结构(3) 第三天 栈的应用:就近匹配/中缀表达式转后缀表达式 、树/二叉树的概念、二叉树的递归与非递归遍历(DLR LDR LRD)、递归求叶子节点数目/二叉树高度/二叉树拷贝和释放...
01 上节课回顾 受限的线性表 栈和队列的链式存储其实就是链表 但是不能任意操作 所以叫受限的线性表 02 栈的应用_就近匹配 案例1就近匹配: #include <stdio.h> in ...
- 利用stack结构,将中缀表达式转换为后缀表达式并求值的算法实现
#!/usr/bin/env python # -*- coding: utf-8 -*-# learn <<Problem Solving with Algorithms and Dat ...
- 前缀表达式与后缀表达式求法(栈的应用)
1.前缀.中缀.后缀表达式 中缀表达式即为人们熟悉的数学运算式子写法.而前缀.后缀表达式是为了计算机计算方便的写法. 前缀表达式是一种没有括号的算术表达式,与中缀表达式不同的是,其将运算符写在前面,操 ...
- 中缀表达式转后缀表达式并求值
因为在学校实在是太闲了,所以写了一个表达式求值的C语言程序,希望大佬可以多多指正. 基本思路: 就像把大象装进冰箱一样,我们需要三步进行表达式的求值工作. 输入一个中缀表达式(就是平常我们见的表达式) ...
最新文章
- 当深度学习遇上异构并行计算
- 适配器模式coding
- Teams App抽奖机器人 - 基础架构
- realloc invalid pointer错误解析
- linux8安装bbr_CentOS 7安装4.9内核开启BBR
- Sybase常用配置参数
- VS2012写的程序在VS2010打开时显示当前版本不兼容
- jsonrpc(jsonrpc4j)demo
- VBA之正则表达式(30)-- 提取机构代码
- SpringSecurity自定义多Provider时提示No AuthenticationProvider found for问题的解决方案与原理(四)
- 操作系统--磁盘调度题目
- Python自动化测试框架,谁才是你的唯一?
- 使用工具清理Windows的winsxs目录
- 电脑水冷,论电脑到底有没有必要装水冷
- js+css实现瀑布流
- Android WiFi only配置
- ValueError: Invalid format specifier
- 银行数字化转型导师坚鹏:数字化转型背景下的银行对公客户营销
- 模拟电路36(理想运算放大器——积分电路、微分电路4)
- 烟草行业IT规划现状、实施及工作重点分析
热门文章
- 苹果在线商店开售官方翻新Retina MacBook Pro
- 基于Select模型的匿名聊天室v1.0
- 在数据可视化这条路上,除了天天做图表,还有更重要的3件事
- 学习《西方哲学史》摘录
- 个人重装系统前备份___1000款最杰出的软件清单:
- 密码学系列之四:一文搞懂序列密码
- 联想小新一键恢复小孔_联想一键恢复系统怎么用?小新Air 13 Pro怎么还原操作系统?...
- MongoDB LBS经纬度查询操作
- 使用CXF+Spring发布WebService,启动报错
- 手机拍的视频后期怎么处理?视频大神的后期技巧,Vlog大片也能做