本篇概述下运用栈(stack),将中缀表达式(infix expression)转换成后缀表达式(postfix expression),并运算结果。

       1. 后缀表达式的运算。

              使用栈运算后缀表达式,是最合适不过了。我们用一个简单的例子来简要Demo下。

              (string/char*) 2 3 5 * + 7 8 * 对表达进行迭代。当迭代值为数字时。将其压入栈中。当迭代值为操作符时,将栈的两个元素弹出,进行运算后将结果压入栈中。

         以此类推,最终获得的栈中剩余的唯一(栈顶)值为运算结果。

       2.中缀表达式转后缀表达式。   

              中缀转后缀。记住一‘天理’般的逻辑,代码就能信手拈来了。当然这天理不是我立的 = = 感谢伟大的 Mark Allen Weiss 的著作-数据结构与算法分析。强力安利下。

              开括号 ( 在栈中优先级最低,在表达式中优先级最高。加减乘除与四则运算的优先级一致。

              栈元素优先级: '*' == '/' > '+' == '-' > '('      表达式元素优先级: '(' > '*' == '/' > '+' == '-'

              若迭代值为数字直接输出,遇操作符对栈中的元素进行检索。

              若栈顶元素相比迭代值的优先级高或相同,输出栈顶元素,弹出,继续检索。若栈内元素优先级相比较低, 则将迭代值压入栈中。

              需留意的时,栈是否为空的检测,栈为空时对操作符进行入栈操作。遇闭括号 ')' 时弹出栈中元素知道栈顶元素为开括号 '(' 。

 

          详细过程见代码注释。

  1 // 对string数式的计算(基于中缀转后缀).cpp : 定义控制台应用程序的入口点。
  2 //
  3 
  4 #include "stdafx.h"
  5 #include <string>
  6 #include <stack>
  7 #include <cctype>
  8 #include <iostream>
  9 
 10 //计算后缀表达式。(int类型)
 11 int postfixExp(const std::string& exp)
 12 {
 13     std::stack<int> numSta;
 14     for (int i = 0; i != exp.size(); i++)
 15     {
 16         //将表达式中的数字压入栈中
 17         std::string num;
 18         while (isdigit(exp[i])) 
 19         {
 20             num.push_back(exp[i]);
 21             i++;
 22         }
 23 
 24         if (!num.empty())  numSta.push(atoi(num.c_str()));
 25 
 26         //遇到空格继续迭代
 27         if (exp[i] == ' ') continue;
 28         
 29         //遇到操作符将栈顶的两个元素弹出并将计算结果压入栈中
 30         if (exp[i] == '+' || exp[i] == '-' || exp[i] == '*' || exp[i] == '/')
 31         {
 32             int num1;
 33             int num2;
 34             if (!numSta.empty())
 35             {
 36                 num1 = numSta.top();
 37                 numSta.pop();
 38             }
 39             if (!numSta.empty())
 40             {
 41                 num2 = numSta.top();
 42                 numSta.pop();
 43             }
 44             //计算
 45             switch (exp[i])
 46             {
 47             case '+': numSta.push(num1 + num2);
 48                 break;
 49             case '-': numSta.push(num2 - num1);
 50                 break;
 51             case '*': numSta.push(num1 * num2);
 52                 break;
 53             case '/': numSta.push(num2 / num1);
 54                 break;
 55             default:
 56                 break;
 57             }
 58         }
 59 
 60     }
 61     return numSta.top();
 62 }
 63 
 64 //中缀转后缀 e.g. 2 + 3 * 5 + (7 * 8  + 9) * 10 ->  2 3 5 * + 7 8 * 9 + 10 * +
 65 std::string infixToPostfix(const std::string& exp)
 66 {
 67     std::string result;
 68     std::stack<char> operators;
 69     for (int i = 0; i < exp.size(); i++)
 70     {
 71         while (isdigit(exp[i]))
 72         {
 73             result.push_back(exp[i]);
 74             i++;
 75         }
 76         //若末尾数字非个位数,数组索引将越界,由于string不是真正意义上的字符数组,越界对结果没有影响
 77         //if (i >= exp.size()) break;
 78         //添加空格分隔符
 79         result.push_back(' ');
 80         //遇到空格继续迭代
 81         if (exp[i] == ' ') continue;
 82         //遇到操作符时,检查栈顶元素优先级,若为高优先级/等优先级操作符,弹出栈中操作符,完成后将表达式的操作符压入
 83         if (exp[i] == '+' || exp[i] == '-')
 84         {
 85             while (!operators.empty() && (operators.top() != '('))
 86             {
 87                 //当栈顶元素不为 ( 时 , ( 在栈中优先级最低,在表达式中优先级最高.
 88                     result.push_back(operators.top());
 89                     operators.pop();
 90                     result.push_back(' ');
 91             }
 92             operators.push(exp[i]);
 93         }
 94         else if (exp[i] == '*' || exp[i] == '/')
 95         {
 96             while (!operators.empty() && (operators.top() == '*' || operators.top() == '/'))
 97             {
 98                 //if (operators.top() == '*' || operators.top() == '/') 若在while内进行判定,当operators不为空时将进入死循环
 99                     result.push_back(operators.top());
100                     operators.pop();
101                     result.push_back(' ');
102             }
103             operators.push(exp[i]);
104         }
105         else if (exp[i] == '(') operators.push('(');
106         else if (exp[i] == ')')
107         {
108             while (operators.top() != '(')
109             {
110                 result.push_back(operators.top());
111                 operators.pop();
112                 result.push_back(' ');
113             }
114             //弹出 ( 
115             operators.pop();
116         }
117         
118     }
119     while (!operators.empty())
120     {
121         result.push_back(operators.top());
122         result.push_back(' ');
123         operators.pop();
124     }
125     
126     return result;
127 }
128 
129 int main()
130 {
131     std::cout << postfixExp(infixToPostfix("2 + 3 * 5 + (7 * 8  + 9) * 10")) << std::endl;
132      system("pause");
133     return 0;
134 }

    

posted on 2016-08-06 01:08  Elapsed_Time  阅读(975)  评论(0编辑  收藏  举报