C++ stack classic question-[expression evaluation]

Given an expression, where the operators only include +,-,*,/ (addition, subtraction, multiplication and division), and may include parentheses, please find the final value of the expression.

Notice:

The data guarantees that the given expression is legal.
The question guarantees that the symbol - will only appear as a minus sign and will not appear as a negative sign. For example, expressions such as -1+2, (2+2)*(-(1+1)+2) will not appear.
The question ensures that all numbers in the expression are positive integers.
The question ensures that the expression does not exceed 231-1 during the intermediate calculation process and the result.
Integer division in the question means rounding to 0, that is to say, results greater than 0 are rounded down, such as 5/3=15/3=1, and results less than 0 are rounded up, such as 5/(1−4 )=−1.
The integer division in C++ and Java is rounded down by default; the integer division in Python // is rounded down by default, so the integer division in Python's eval() function is also rounded down and cannot be used directly in this question.
The input format
is one line in total, which is the given expression.

The output format
is one line in total, which is the result of the expression.

Data range
The length of the expression cannot exceed 105.

Input sample:
(2+2)*(1+1)
Output sample:
8

#include<iostream>
#include<cstring>
#include<algorithm>
#include<stack>
#include<unordered_map>
using namespace std;

//双栈
stack<int>num;
stack<char>op;

//求值函数,使用末尾的运算符操作末尾的两个数
void eval()
{
    auto b = num.top(); num.pop();//第二个操作数
    auto a = num.top(); num.pop();//第一个操作数
    auto c = op.top(); op.pop();  //运算符

    int x;                        //结果计算(注意顺序)
    if (c == '+')x = a + b;
    else if (c == '-')x = a - b;
    else if (c == '*')x = a * b;
    else x = a / b;
    num.push(x);                  //结果入栈
}

int main()
{
    //优先级表
    unordered_map<char, int>pr{ {'+',1},{'-',1},{'*',2},{'/',2} };

    //读入表达式
    string str;
    cin >> str;

    //从前往后扫描表达式
    for (int i = 0; i < str.size(); i++)
    {
        auto c = str[i];
        //扫描到数字,使用双指针法一直读入
        if (isdigit(c))
        {
            //j表示扫描到数字的指针
            int x = 0, j = i;
            while (j < str.size() && isdigit(str[j]))
                x = x * 10 + str[j++] - '0';
            //更新i指针
            i = j - 1;
            //数字入栈
            num.push(x);
        }
        //左括号直接入栈
        else if (c == '(')op.push(c);
        //右括号出现,从右往左计算栈中数据,直到遇见左括号
        else if (c == ')')
        {
            //不断使用eval函数对末尾数字运算
            while (op.top() != '(')eval();
            //弹出左括号
            op.pop();
        }
        //扫描到运算符
        else
        {
            //如果栈顶运算符优先级较高,先操作栈顶元素再入栈
            while (op.size() && pr[op.top()] >= pr[c])eval();
            //如果栈顶运算符优先级较低,直接入栈
            op.push(c);
        }
    }
    //把没有操作完的运算符从右往左操作一遍
    while (op.size())eval();
    //栈顶元素为最终答案
    cout << num.top() << endl;
    return 0;
}

Guess you like

Origin blog.csdn.net/m0_74153798/article/details/131789546