首页 > 代码库 > 栈的应用 — 中缀式转后缀式

栈的应用 — 中缀式转后缀式

由中缀式转换成后缀式,同样使用栈,并运用一些规则来完成。规则介绍如下:
  • 当读到的是操作数,立即输出。
  • 当读到的是运算符,则先从栈中弹出优先级高于自己的运算符(不包含括号),自己入栈。
  • 读到左括号入栈,读到右括号则将栈中元素出栈并输出,直到遇见左括号(括号都不输出)。
  • 输入为空后,将栈元素弹出并输出直到栈空。
注意,最后生成的后缀表达式是考虑了运算符优先级的,再配合逆波兰的无优先级概念这一性质,就能够编写出一个带运算符优先级和括号的简易计算器了。

下面是完整的计算器代码,整型四则运算,可加括号。写了一个下午,幸苦呀~
#include <iostream>
#include <vector>
#include <stack>
#include <ctype.h>
#include <cstdlib>
#include <sstream>
 
using namespace std;
 
bool IsDigit(string str)
{
    for(int i = 0; i < str.size(); i++)
        if ((str.at(i) > ‘9‘) || (str.at(i) < ‘0‘))
            return false;
    return true;
}
 
int main()
{
    stack<string> s;
    vector<string> postfix; // 存放后缀表达式,作为求运算结果的输入
    string input;
 
    while (cin >> input)
    {
        if (IsDigit(input))
            //cout << input << ‘ ‘;
            postfix.push_back(input);
        else if (input == "(")
            s.push(input);
        else if (input == "+" || input == "-")
        {
            while ((!s.empty()) && (s.top() != "("))
            {   // 弹出优先级大于等于“+”“-”的运算符直到遇到“(”
                //cout << s.top() << ‘ ‘;
                postfix.push_back(s.top());
                s.pop();
            }
            s.push(input);
        }
        else if (input == "*" || input == "/")
        {
            // 在不知道栈是否为空时,不能top()
            while ((!s.empty()) && (s.top() != "(") &&
                        (s.top() != "+") && (s.top() != "-"))
            {   // 弹出运算符“*”“/”直到遇到“(”
                //cout << s.top() << ‘ ‘;
                postfix.push_back(s.top());
                s.pop();
            }
            s.push(input);
        }
        else if (input == ")")
        {
            while ((!s.empty()) && (s.top() != "("))
            {   // 弹出直到遇到“(”
                //cout << s.top() << ‘ ‘;
                postfix.push_back(s.top());
                s.pop();
            }
            s.pop();    // 弹出“(”
        }
        else
        {   // 遇到非法字符
            cout << "Input illegal";
            return -1;
        }
    }
 
    while (!s.empty())
    {
        //cout << s.top() << ‘ ‘;
        postfix.push_back(s.top());
        s.pop();
    }
 
    vector<string>::iterator iter = postfix.begin();
    for ( ; iter != postfix.end(); iter++)
        cout << *iter;
 
#if 1
    cout << endl;
 
    iter = postfix.begin();
 
    while (iter != postfix.end())
    {
        input = *iter;
        if (IsDigit(input))
            s.push(input);
        else if ((input == "+") || (input == "-") || (input == "*") || (input == "/"))
        {
            int lhs = atoi((s.top()).c_str());
            s.pop();
            int rhs = atoi((s.top()).c_str());
            s.pop();
 
            stringstream ss;
            string midval;
            switch (*input.c_str())
            {
                case ‘+‘ :
                    ss << (lhs+rhs);
                    ss >> midval;
                    s.push(midval);
                    break;
                case ‘-‘ :
                    ss << (lhs-rhs);
                    ss >> midval;
                    s.push(midval);
                    break;
                case ‘*‘ :
                    ss << (lhs*rhs);
                    ss >> midval;
                    s.push(midval);
                    break;
                case ‘/‘ :
                    ss << (rhs/lhs);    // 注意除法的操作数有顺序限制
                    ss >> midval;
                    s.push(midval);
                    break;
            }
        }
 
        iter++;
    }
 
    cout << s.top();
#endif
    return 0;
}


参考:
《数据结构于算法分析》 P54。