简介

中缀表示法(或中缀记法)是一个通用的算术或逻辑公式表示方法, 操作符是以中缀形式处于操作数的中间(例:3 + 4)。与前缀表达式(例:+ 3 4)或后缀表达式(例:3 4 +)相比,中缀表达式不容易被电脑解析,但仍被许多程序语言使用,因为它符合人们的普遍用法。

逆波兰表示法(Reverse Polish notation,RPN,或逆波兰记法),是一种是由波兰数学家扬·武卡谢维奇1920年引入的数学表达式方式,在逆波兰记法中,所有操作符置于操作数的后面,因此也被称为后缀表示法。逆波兰记法不需要括号来标识操作符的优先级。

目的

将中缀表达式(即标准的表达式)转换为后缀表达式

例如:1+2*3+(4*5+6)*7 转换成 123*+45*6+7*+

转换原则:

  1. 当读到一个操作数时,立即将它放到输出中。操作符不立即输出,放入栈中。遇到圆括号也是推入栈中。

  2. 如果遇到一个右括号,那么就将栈元素弹出,将符号写出直到遇到一个对应的左括号。但是这个左括号只被弹出,并不输出。

  3. 在读到操作符时,如果此时栈顶操作符优先级大于或等于此操作符,弹出栈顶操作符直到发现优先级更低的元素位置。除了处理‘)’的时候,否则决不从栈中移走‘(’。操作符中,‘+’和‘-’优先级最低,‘*’和‘/’优先级中等,‘(’和‘)’最高。

  4. 如果读到输入的末尾,将栈元素弹出直到该栈为空,将符号写到输出中。

实例

首先,读入‘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;
}

利用栈实现中缀表达式转后缀表达式相关推荐

  1. java利用栈求复杂表达式_java中的栈Stack的基本使用和应用(二) ——利用栈计算合法的算术表达,中缀表达式转后缀表达式...

    利用栈Stack计算合法的算术表达式 限定的算术表达式求值问题:包含 "+"."-"."*"."/" .正整数和圆括号的 ...

  2. 数据结构——栈——中缀表达式和后缀表达式

    什么是中缀表达式,什么是后缀表达式 我们一般看见的多项式计算都是中缀表达式构成的:1+2*3+4/3 类似这种,为什么说是中缀呢?因为它的计算符号都是在两个数中间的. 那么自然而然的明白了后缀表达式是 ...

  3. 栈应用(中缀表达式转后缀表达式并计算后缀表达式的值)

    [0]README 0.1) 本文旨在总结 中缀表达式转后缀表达式并计算后缀表达式的值 的步骤,并给出源代码实现: 0.2) 本文中涉及到的源代码均为原创,是对中缀转后缀和计算后缀的简单实现,(旨在理 ...

  4. 数据结构 - 栈 (逆波兰计算器)(栈的三种表达式)(前缀、中缀和后缀表达式,后缀也叫逆波兰表达式)(中缀表达式转后缀表达式实现步骤及完整代码)

    栈的三种表达式:前缀.中缀和后缀表达式,后缀也叫逆波兰表达式 前缀(波兰表达式) 中缀(对人来讲很好理解,对于计算机来讲就方便了,一般会把中缀表达式转换成后缀表达式) 后缀(逆波兰表达式) 计算过程 ...

  5. 使用栈实现中缀表达式转为后缀表达式和后缀表达式的求解

    书籍在线网址http://interactivepython.org/runestone/static/pythonds/index.html 中文翻译书籍:https://facert.gitboo ...

  6. 栈应用:中缀表达式转后缀表达式

    网上有很多关于中缀转后缀的文章,很多文章或多或少都有bug,包括一些教学视频,经过本人无数次测试,保证下面的代码运算结果的正确性!前提是你写的中缀表达式是正确的哈,没有做中缀表达式是否正确的的完整性校 ...

  7. 数据结构(3) 第三天 栈的应用:就近匹配/中缀表达式转后缀表达式 、树/二叉树的概念、二叉树的递归与非递归遍历(DLR LDR LRD)、递归求叶子节点数目/二叉树高度/二叉树拷贝和释放...

    01 上节课回顾 受限的线性表 栈和队列的链式存储其实就是链表 但是不能任意操作 所以叫受限的线性表 02 栈的应用_就近匹配 案例1就近匹配: #include <stdio.h> in ...

  8. 利用stack结构,将中缀表达式转换为后缀表达式并求值的算法实现

    #!/usr/bin/env python # -*- coding: utf-8 -*-# learn <<Problem Solving with Algorithms and Dat ...

  9. 前缀表达式与后缀表达式求法(栈的应用)

    1.前缀.中缀.后缀表达式 中缀表达式即为人们熟悉的数学运算式子写法.而前缀.后缀表达式是为了计算机计算方便的写法. 前缀表达式是一种没有括号的算术表达式,与中缀表达式不同的是,其将运算符写在前面,操 ...

  10. 中缀表达式转后缀表达式并求值

    因为在学校实在是太闲了,所以写了一个表达式求值的C语言程序,希望大佬可以多多指正. 基本思路: 就像把大象装进冰箱一样,我们需要三步进行表达式的求值工作. 输入一个中缀表达式(就是平常我们见的表达式) ...

最新文章

  1. 当深度学习遇上异构并行计算
  2. 适配器模式coding
  3. Teams App抽奖机器人 - 基础架构
  4. realloc invalid pointer错误解析
  5. linux8安装bbr_CentOS 7安装4.9内核开启BBR
  6. Sybase常用配置参数
  7. VS2012写的程序在VS2010打开时显示当前版本不兼容
  8. jsonrpc(jsonrpc4j)demo
  9. VBA之正则表达式(30)-- 提取机构代码
  10. SpringSecurity自定义多Provider时提示No AuthenticationProvider found for问题的解决方案与原理(四)
  11. 操作系统--磁盘调度题目
  12. Python自动化测试框架,谁才是你的唯一?
  13. 使用工具清理Windows的winsxs目录
  14. 电脑水冷,论电脑到底有没有必要装水冷
  15. js+css实现瀑布流
  16. Android WiFi only配置
  17. ValueError: Invalid format specifier
  18. 银行数字化转型导师坚鹏:数字化转型背景下的银行对公客户营销
  19. 模拟电路36(理想运算放大器——积分电路、微分电路4)
  20. 烟草行业IT规划现状、实施及工作重点分析

热门文章

  1. 苹果在线商店开售官方翻新Retina MacBook Pro
  2. 基于Select模型的匿名聊天室v1.0
  3. 在数据可视化这条路上,除了天天做图表,还有更重要的3件事
  4. 学习《西方哲学史》摘录
  5. 个人重装系统前备份___1000款最杰出的软件清单:
  6. 密码学系列之四:一文搞懂序列密码
  7. 联想小新一键恢复小孔_联想一键恢复系统怎么用?小新Air 13 Pro怎么还原操作系统?...
  8. MongoDB LBS经纬度查询操作
  9. 使用CXF+Spring发布WebService,启动报错
  10. 手机拍的视频后期怎么处理?视频大神的后期技巧,Vlog大片也能做