对于简单的四则运算而言,后缀表达式可以通过使用栈(stack)快速算出结果

==================================我是分割线====================================

后缀的定义:

e.g. 2 + 3 -> 2 3 +

2 + 3 * 4 -> 2 3 4 * +

应用栈来计算后缀表达式:

e.g. 后缀表达式 6 5 2 3 + 8 * + 3 + *

遍历:     6     push(6)                                  stack: 6

5     push(5)                                   stack: 6 5

2     push(2)                                   stack: 6 5 2

       3     push(3)                                 stack: 6 5 2 3

+     pop、pop 2、 3出栈,操作 ans = 2 + 3; push(ans)         stack: 6 5 5

8    push(8)                                  stack: 6 5 5 8

*     pop、pop 5、 8出栈,操作 ans = 5 * 8; push(ans)           stack: 6 5 40

+     pop、pop 5、 40出栈,操作 ans = 5 + 40; push(ans)       stack: 6 45

3     push(3)                                   stack: 6 45 3

+     pop、pop 45、 3出栈,操作 ans = 45 + 3; push(ans)        stack: 6 48

*      pop、pop 6、 48出栈,操作 ans = 6 * 48; push(ans)         stack: 288

把中缀表达式转化成后缀表达式:

  设定: 优先级 ‘(’  >  ‘*’  =  ‘/’  >  ‘+’  =  ‘-’

  ①读取输入队列的字符,判断是数字还是符号+-*/()

  ②若是数字,放到输出队列

  ③若是‘)’,则把stack中的符号一一弹出到输出队列,直到遇到第一个‘(’,且‘(’不用放到输出队列

  ④若是其他符号+-*/(,则把栈中元素弹出,直到发现优先级更低的符号或者‘(’为止。'('只有在遇到‘)’时才弹出

代码实现:

 

 //2016-03-16
//中缀转后缀 //局限性:输入合法、数字为0~9的范围
#include <iostream>
#include <string>
#include <stack> using namespace std; int main() {
string input, output;
stack<char> operators;
while (cin >> input) {
if (input == "") break;
output.clear();
for (int i = ; i < input.size(); i++) {
char ch = input[i];
if (ch >= '' && ch <= '') output.push_back(ch);
else if (ch == '+' || ch == '-') {
while (!operators.empty() && (operators.top() == '*' || operators.top() == '/' || operators.top() == '-' || operators.top() == '+')) {
output.push_back(operators.top());
operators.pop();
}
operators.push(ch);
}
else if (ch == '*' || ch == '/') {
while (!operators.empty() && (operators.top() == '*' || operators.top() == '/')) {
output.push_back(operators.top());
operators.pop();
}
operators.push(ch);
}
else if (ch == ')') {
while (operators.top() != '(' && !operators.empty()) {
output.push_back(operators.top());
operators.pop();
}
operators.pop();
}
else if (ch == '(') {
operators.push(ch);
}
}
while (!operators.empty()) {
output.push_back(operators.top());
operators.pop();
}
cout << "output : " << output << endl;
}
return ;
}

测试:

  

局限性:(不够健壮)

  ①只实现了0~9的数字输入,若是两位以上的数字还需要做字符判断(前一个字符是否是数字,若是,则当前字符和前一位同属一个整数)

   ②没有做最后的结果计算,因为还是字符串,如果需要,则要做字符到整型的转换判断。

   ③没有异常检测(假设所有输入都合法,不合法的输入会直接导致错误输出)

一些bugs

  ①stack容器内没有clear();

  ②判断条件while (!operators.empty() && (operators.top() == '*' || operators.top() == '/'))中必须先判断!operators.empty()

    否则先判断(operators.top() == '*' || operators.top() == '/')事实上是会做top()的读取操作,此时栈若为空,就会runtime error

【C++】朝花夕拾——中缀转后缀的更多相关文章

  1. 栈的应用1——超级计算器(中缀与后缀表达式)C语言

    这里要学的程序主要用来实现一个功能——输入表达式输出结果,也就是一个计算器.效果如下: 这个程序主要有两个步骤:1.把中缀表达式转换为后缀表达式:2.计算后缀表达式的结果. 首先先明白几个问题: 1. ...

  2. C语言 中缀转后缀

    给定字符串型的算术表达式,实现中缀转后缀并运算得出结果: #ifndef STACK_H_INCLUDED #define STACK_H_INCLUDED #include <stdio.h& ...

  3. Java数据结构和算法(六)——前缀、中缀、后缀表达式

    前面我们介绍了三种数据结构,第一种数组主要用作数据存储,但是后面的两种栈和队列我们说主要作为程序功能实现的辅助工具,其中在介绍栈时我们知道栈可以用来做单词逆序,匹配关键字符等等,那它还有别的什么功能吗 ...

  4. C++ 中缀转后缀表达式并求值

    //中缀转后缀 #include<iostream> #include<stack> using namespace std; int prio(char x){ ; ; ; ...

  5. Java数据结构和算法(六):前缀、中缀、后缀表达式

    前面我们介绍了三种数据结构,第一种数组主要用作数据存储,但是后面的两种栈和队列我们说主要作为程序功能实现的辅助工具,其中在介绍栈时我们知道栈可以用来做单词逆序,匹配关键字符等等,那它还有别的什么功能吗 ...

  6. java四则运算----前缀、中缀、后缀表达式

    接到一个新需求,需要实现可配置公式,然后按公式实现四则运算. 刚拿到需求,第一反应就是用正则匹配‘(’,‘)’,‘+’,‘-’,‘*’,‘/’,来实现四则运算,感觉不复杂. 然后开始coding.发现 ...

  7. 洛谷P1981 表达式求值 题解 栈/中缀转后缀

    题目链接:https://www.luogu.org/problem/P1981 这道题目就是一道简化的中缀转后缀,因为这里比较简单,只有加号(+)和乘号(*),所以我们只需要开一个存放数值的栈就可以 ...

  8. PTA-7-20 表达式转换(中缀转后缀,带括号,负数,小数转换)

    本题考点:中缀表达式转后缀表达式. 难点: 带有小数的数字 数字可能带有正负号 题目描述: 算术表达式有前缀表示法.中缀表示法和后缀表示法等形式.日常使用的算术表达式是采用中缀表示法,即二元运算符位于 ...

  9. 数据结构之栈—强大的四则复杂运算计算器(超过windows自带的科学计算器)【中缀转后缀表达式】

    比windows自带计算器还强的四则复杂运算计算器! 实测随机打出两组复杂算式:-7.5 * 6 / ( -2 + ( -6.5 -  -5.22 ) )与7.5+-3*8/(7+2) windows ...

随机推荐

  1. 网页瞬间转换成桌面应用级程序(IOS/Win/Linux)

    首先下载node,并且安装. 安装检测 检测完成后,执行下面这条命令 npm i -g nativefier 安装完成后 执行下面的命令+网址即可生成任意的桌面级程序 示例:nativefier &q ...

  2. android的ndk学习(1)

    android的ndk学习(1)   之前学了一段时间ndk,总认为要总结一下.ndk使得很方便地实现java和C与C++代码的相互沟通.合理地掌握使用ndk能够提高应用程序的运行效率.所以对于学习a ...

  3. frameset怎样实现整个页面的跳转

    登录页面login.jsp,系统登录成功后展示mainLayout.jsp, 我如今用frameset框架把页面mainLayout.jsp分为三部分,head.jsp..left.jsp.right ...

  4. 斜率优化专题1——bzoj 1597 [Usaco2008 Mar] 土地购买 题解

    转载请注明:http://blog.csdn.net/jiangshibiao/article/details/24387147 [原题] 1597: [Usaco2008 Mar]土地购买 Time ...

  5. 解决ES集群状态异常教程(存在UNASSIGNED)

    解决ES集群状态异常教程(存在UNASSIGNED)_百度经验 https://jingyan.baidu.com/article/9158e00013f787a255122843.html

  6. 一位ACMer过来人的心得(转)

    刻苦的训练我打算最后稍微提一下.主要说后者:什么是有效地训练? 我想说下我的理解.很多ACMer入门的时候,都被告知:要多做题,做个500多道就变牛了.其实,这既不是充分条件.也不会是必要条件. 我觉 ...

  7. RDA 工模

    1.工模GUI如下图: 注意两个API接口,_APP_Update_Layer()/UpdateNodeFunctionContent() 这两个接口一个是刷新ListView,另一个刷新ListVi ...

  8. uva1560

    In an extended version of the game Lights Out®, is a puzzle with 5 rows of 6 buttons each (the actua ...

  9. 什么是需求Bug、设计Bug、功能bug?

    首先什么是需求Bug.设计Bug.功能bug? 需求Bug,指由于客户需求描述不清晰或错误.需求收集人员自身原因及需求本身模糊难于分析.获取等原因,导致客户需求获取不准确,后期产品不能满足客户.用户的 ...

  10. mybatis批量update操作的写法,及批量update报错的问题解决方法

    mybatis的批量update操作写法很简单,如下: public interface YourMapper extends BaseMapper<YourExt> { void upd ...