• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

【C++】朝花夕拾——中缀转后缀

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

对于简单的四则运算而言,后缀表达式可以通过使用栈(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中的符号一一弹出到输出队列,直到遇到第一个‘(’,且‘(’不用放到输出队列

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

代码实现:

 

 1 //2016-03-16
 2 //中缀转后缀
 3 
 4 //局限性:输入合法、数字为0~9的范围
 5 #include <iostream>
 6 #include <string>
 7 #include <stack>
 8 
 9 using namespace std;
10 
11 int main() {
12     string input, output;
13     stack<char> operators;
14     while (cin >> input) {
15         if (input == "0") break;
16         output.clear();
17         for (int i = 0; i < input.size(); i++) {
18             char ch = input[i];
19             if (ch >= '0' && ch <= '9') output.push_back(ch);
20             else if (ch == '+' || ch == '-') {
21                 while (!operators.empty() && (operators.top() == '*' || operators.top() == '/' || operators.top() == '-' || operators.top() == '+')) {
22                     output.push_back(operators.top());
23                     operators.pop();
24                 }
25                 operators.push(ch);
26             }
27             else if (ch == '*' || ch == '/') {
28                 while (!operators.empty() && (operators.top() == '*' || operators.top() == '/')) {
29                     output.push_back(operators.top());
30                     operators.pop();
31                 }
32                 operators.push(ch);
33             }
34             else if (ch == ')') {
35                 while (operators.top() != '(' && !operators.empty()) {
36                     output.push_back(operators.top());
37                     operators.pop();
38                 }
39                 operators.pop();
40             }
41             else if (ch == '(') {
42                 operators.push(ch);
43             }
44         }
45         while (!operators.empty()) {
46             output.push_back(operators.top());
47             operators.pop();
48         }
49         cout << "output : " << output << endl;
50     }
51     return 0;
52 }

 

测试:

  

 

局限性:(不够健壮)

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

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

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

 

一些bugs

  ①stack容器内没有clear();

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

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


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
C#------如何深度克隆一个对象发布时间:2022-07-14
下一篇:
【C#】回调方法不通过object参数获得委托实例发布时间:2022-07-14
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap