逆波兰表达式

  • 一.定义
  • 二.逆波兰式的意义
  • 三.逆波兰式的实现
    • 1.方法
      • (1)中缀表达式转化为后缀表达式
      • (2)由后缀表达式计算结果
    • 2.代码实现

一.定义

逆波兰式,又称后缀表达式,指的是操作符在其所控制的操作数后面的表达式。
举个例子,1 + 2 * 3 - 4这个表达式是我们熟悉的中缀表达式,那么其所对应的后缀表达式为:1 2 3 * + 4 -
再来个复杂的例子:1 * (2 + 3) / 5 - 4 / 2其对应的后缀表达式为:1 2 3 + * 5 / 4 2 / -(其中括号由于只是提升表达式优先级的作用,因此不放入后缀表达式中)。

二.逆波兰式的意义

为什么要将看似简单的中缀表达式转换为复杂的逆波兰式,原因就在于这个简单是相对我们人类的思维结构来说的,对计算机而言中序表达式是非常复杂的结构。相对的,逆波兰式在计算机看来却是比较简单易懂的结构。因为计算机普遍采用的内存结构是栈式结构,它执行先进后出的顺序。

三.逆波兰式的实现

1.方法

(1)中缀表达式转化为后缀表达式

对于给出的中缀表达式,如何将其转化为后缀表达式呢?
第一,若遇到操作数则直接输出/存储。
第二,遇到操作符,若此时栈为空或者操作符优先级高于栈顶,则入栈。
第三,若操作符的优先级低于或者等于栈顶,则出栈直至栈空或者优先级低于该操作符。
第四,遇到’(’,其后的所有操作符(直至遇到’)’)按上述操作入栈或出栈;当遇到’)‘时,将’('顶上的所有操作符出栈。

(2)由后缀表达式计算结果

第一,遇到操作数则入栈。
第二,遇到操作符则将栈顶的两个操作数出栈,其中第一个数为右操作数,第二个数为左操作数。
第三,计算结果并将计算的结果入栈。
第四,最后栈顶的结果即为所计算的结果。

2.代码实现

#include <iostream>
#include <string>
#include <stack>
#include <vector>
using namespace std;string trans(string& s)
{string operand;stack<char> Operator;int flag = 0;//记录括号优先级for (const auto& e : s){if (e == '('){Operator.push(e);flag = 1;continue;}if (e == ')'){flag = 0;while (Operator.top() != '('){operand.push_back(Operator.top());Operator.pop();}Operator.pop();continue;}//操作符if (e == '+' || e == '-' || e == '*' || e == '/'){if (flag == 1){if (Operator.top() == '('){Operator.push(e);}else if ((e == '*' || e == '/') && (Operator.top() == '+' || Operator.top() == '-')){Operator.push(e);}else//操作符的优先级低于或等于栈顶操作符则出栈,直至遇到'('{while (Operator.top() != '('){operand.push_back(Operator.top());Operator.pop();}Operator.push(e);}}else if (Operator.empty())//栈空就入栈{Operator.push(e);}//操作符的优先级高于栈顶操作符,入栈else if ((e == '*' || e == '/') && (Operator.top() == '+' || Operator.top() == '-')){Operator.push(e);}else//操作符的优先级低于或等于栈顶操作符则出栈,直至栈空或者优先级高于栈顶操作符{while (!Operator.empty()){operand.push_back(Operator.top());Operator.pop();}Operator.push(e);}}//操作数else{operand.push_back(e);}}while (!Operator.empty()){operand.push_back(Operator.top());Operator.pop();}return operand;
}int evalRPN(const string& s)
{stack<char> operand;int left = 0, right = 0;for (const auto& e : s){if (e == '+' || e == '-' || e == '*' || e == '/'){switch (e){case '+':right = operand.top();operand.pop();left = operand.top();operand.pop();operand.push(left + right);break;case '-':right = operand.top();operand.pop();left = operand.top();operand.pop();operand.push(left - right);break;case '*':right = operand.top();operand.pop();left = operand.top();operand.pop();operand.push(left * right);break;case '/':right = operand.top();operand.pop();left = operand.top();operand.pop();operand.push(left / right);break;}}else//操作数{operand.push(e - '0');}}return operand.top();
}int RPN(const string& str)
{//1.中缀表达式转化为后缀表达式string s(str);s = trans(s);//2.后缀表达式计算答案return evalRPN(s);
}int main()
{string s("1*(2*3+5)/5-4/2");int ret = RPN(s);cout << "ret:" << ret << endl;return 0;
}

结果:

【C++】栈的应用:逆波兰式的实现相关推荐

  1. 数据结构——逆波兰式

    很久没有关注算法和数据结构,大部分知识都已经忘记了:是时间好好回炉一下了,说实话干读数据机构这本书还是挺枯燥而且这本书原理性比较多,有一定的难度.这不刚看到逆波兰式废了好大劲才搞懂,老了... 逆波兰 ...

  2. 【C语言】算法学习·逆波兰式

    目录 逆波兰式 算法定义 算法作用 算法实现 计算方法 算法举例 算法图示 程序实现 二叉树法 逆波兰式 算法定义 一个表达式E的后缀形式可以如下定义: (1)如果E是一个变量或常量,则E的后缀式是E ...

  3. 对逆波兰式的简单理解

    前言: 人是比较喜欢中缀式的,因为它符合人们的运算习惯:但是机器是不喜欢中缀式,它更喜欢后缀式,也就是逆波兰式. 逆波兰式的理解: 1.逆波兰式: ab35c-*+= 2.计算机计算过程: 策略:计算 ...

  4. C语言编程对一个逆波兰式进行求值,算式与逆波兰式

    致憨憨的从前 当年,老师布置一道作业:编写一个计算器,要求输入算式,给出结果.算式中只包含+-*/^这几个运算符,算式中不含负数.由于是Python课程,我很快给出了解题方式,如下: while Tr ...

  5. 使用栈解决的一类经典问题:表达式转换及求值;中缀表达式;前缀表达式,后缀表达式,中缀转前缀;中缀转后缀;后缀表达式求值;波兰式,逆波兰式

    文章目录 背景知识 表达式转换问题(考研经典) 一:手工转换 (1)中缀转前缀和中缀转后缀 (2)前缀转中缀和后缀转中缀 二:用栈实现表达式转换 (1)中缀转后缀 (2)中缀转前缀 表达式计算问题(使 ...

  6. DS栈—波兰式,逆波兰式

    题目描述 表达式有三种表示方法,分别为: 前缀表示(波兰式):运算符+操作数1+操作数2 中缀表示:操作数1+运算符+操作数2 后缀表示(逆波兰式):操作数1+操作数2+运算符 例如:a +b * ( ...

  7. 栈的应用 - 波兰式与逆波兰式

       上一篇笔记中,简单讲到了栈的特性,并且给出了栈的实现,现在要利用栈来实现表达式的求值问题.    有三个名词与表达式的计算密切相关,分别是中缀表达式.前缀表达式和后缀表达式,它们都是表达式的一种 ...

  8. D. DS栈—波兰式,逆波兰式(dsoj c++)

    题目描述 表达式有三种表示方法,分别为: 前缀表示(波兰式):运算符+操作数1+操作数2 中缀表示:操作数1+运算符+操作数2 后缀表示(逆波兰式):操作数1+操作数2+运算符 例如:a +b * ( ...

  9. php逆波兰表达式,PHP根据数字的字符表达式计算出结果(转换成逆波兰式再求解)[转]...

    这个简单的计算器采用的是逆波兰式来做的,仅支持加减乘除四种运算,纯粹个人练习记录一下,还望多多支持. 用法 require 'Calc.php'; $calc = new Calc('(1+9)/2' ...

最新文章

  1. Kali Linux***测试
  2. (转译)用FFmpeg和SDL写播放器--01视频帧提取
  3. eclipse格式化代码
  4. Spring的事件发布机制
  5. python分配buffer_Node.js中的buffer如何和python中的buffer相对应
  6. 【CyberSecurityLearning 16】单臂路由与DHCP中继+ ICMP协议+VTP
  7. adr和ldr的区别
  8. Zookeeper基于Java 访问
  9. rabbitmq channel参数详解【转】
  10. 1.Redis简介与基本命令
  11. Mr.J--Javascript表格创建 模糊搜索 关键词搜索
  12. Windows下配置多个Tomcat9
  13. CSS雪碧,即CSS Sprite 简单的例子
  14. *第四周*数据结构实践项目一【创建单链表】
  15. webstorm 2017 激活破解方法大全
  16. html 样式之style属性的使用
  17. 信奥中的数学:斐波那契数列
  18. coreldraw x4怎么写字_CorelDRAW实例:给文字排版的几个小技巧(4)
  19. PS新手如何快速抠白色背景的玻璃瓶
  20. 【财经期刊FM-Radio|2020年11月14日】

热门文章

  1. Java Scanner类的方法及用法(很详细)
  2. 2020/7/17 积分不等式/反常积分/定积分应用
  3. 兼容微信6.74 ios12版本
  4. MATLAB中的积分运算
  5. openCV中二值化图像的方法
  6. 程序员找工作的个人经验及注意事项
  7. 红米android10参数,红米10x5g手机参数红米10x5g手机参数有哪些
  8. 5、标尺-参考线-网格
  9. 已注销主体的公众号迁移办理流程及方法
  10. spring事务管理方式