中缀表达式求值

  利用栈求中缀表达式的值.

  它的要点是找到运算符的优先级,比如一个式子 3 + (4 + 3 * 5) ,扫到+号是不能算的,它的级别高于'\0'(首先给运算符栈压入一个'\0'),扫到左括号也不能算,直到扫到右括号,它之前的 '*' 是比它优先级高的. 这种运算符优先级要利用一个二维数组,然后查表.

  对于运算符和运算数,要开两个栈,当扫到运算数时要果断将其压栈,扫到运算符时,如果栈顶运算符级别高于它,将进行计算,同时要将运算数栈的顶端两个数弹出,将计算结果再压入栈. 如果栈顶运算符级别等于扫到的运算符就说明这两个运算符可以抵消了,所以将弹出顶端运算符. 如果栈顶运算符级别小于它就要将它压入运算符栈待用.

#include <iostream>
#include <stack>
#include <cstring>
using namespace std;
char s[260];
int n1 = 0, n2 = 0;
char pri[8][9] =
{
    ">><<<<>>",
    ">><<<<>>",
    ">>>><<>>",
    ">>>><<>>",
    ">>>>><>>",
    "<<<<<<= ",
    "        ",
    "<<<<<< ="
};
int sw(char s)
{
    if (s == '+') return 0;
    else if (s == '-') return 1;
    else if (s == '*') return 2;
    else if (s == '/') return 3;
    else if (s == '^') return 4;
    else if (s == '(') return 5;
    else if (s == ')') return 6;
    else if (s == '\0')return 7;
    else return -1;
}
int cal(int n1, char rt, int n2)
{
    if (rt == '+') return n1 + n2;
    else if (rt == '-') return n1 - n2;
    else if (rt == '*') return n1 * n2;
    else if (rt == '/') return n1 / n2;
    else if (rt == '^')
    {
        int ans = 1;
        for (int i = 1; i <= n2; i++)
            ans *= n1;
        return ans;
    }
    else return -1;
}
stack <int> opnd;
stack <char> optr;
int main()
{
  
    int result = 0, i = 0;
    optr.push('\0');
    cin >> s;

    while (!optr.empty())
    {
        char c = s[i];
        if (isdigit(c))
        {
            opnd.push(c - '0');
            i++;
        }
        
        else
        {
            char cmp = pri[sw(optr.top())][sw(s[i])];
            if (cmp == '<')
            {
                optr.push(s[i]);
                i++;
            }
            else if (cmp == '=')
            {
                optr.pop();
                i++;
            }
            else if (cmp == '>')
            {
                    n2 = opnd.top() ;
                    opnd.pop();
                    n1 = opnd.top() ;
                    opnd.pop();
                    result = cal(n1, optr.top(), n2);
                    opnd.push(result);
                    optr.pop();
                    
                
            }
        }
    }
    cout << opnd.top() << endl;
    return 0;
    
}

  

  

  

猜你喜欢

转载自www.cnblogs.com/XCuber/p/9063440.html