使用符号栈和数值栈,在当前符号优先级高于栈顶符号时进栈,优先级等于和小于时出栈执行计算。左括号必须进栈,但优先级设置为最低,右括号必出栈直到对应的左括号出栈。

#include <iostream>
#include <vector>
#include <sstream>
using namespace std;


void pop_and_cal(vector<int> &values, vector<char> &ops) {
    char op = ops.back();
    ops.pop_back();
    int num2 = values.back();
    values.pop_back();
    int num1 = values.back();
    values.pop_back();
    int result = 0;
    switch(op) {
        case '+': result = num1 + num2; break;
        case '-': result = num1 - num2; break;
        case '*': result = num1 * num2; break;
        case '/': result = num1 / num2; break;
    }
    values.push_back(result);
}

// 处理正负号,统一括号
string preprocess(string line) {
    stringstream ss;
    bool last_is_value = false; 

    for(char c : line) {
        // 给正负号前加一个数字0
        if (!last_is_value 
            && (c == '-' || c == '+')) {
            ss << 0;
        }
        // 替换括号
        switch(c) {
            case '[':
            case '{': c = '('; break;
            case ']':
            case '}': c = ')'; break;
        }
        if ((c >= '0' && c <= '9')
           || c == ')') {
            last_is_value = true;
        } else {
            last_is_value = false;
        }
        ss << c;
    }
    return ss.str();
}

int cal(string &raw_exp) {
    int prior[128] = {0};
    vector<int> values;
    vector<char> ops;
    string exp = preprocess(raw_exp);

    prior['('] = 0;
    prior[')'] = 0;
    prior['+'] = 10;
    prior['-'] = 10;
    prior['*'] = 20;
    prior['/'] = 20;

    int state = 0;
    int i = 0;

    while(i < exp.size()) {
        char c = exp[i];
        if ( c >= '0' && c <= '9') {
            int value;
            stringstream ss;
            // 读取数字的所有位
            while(i < exp.size()) {
                c = exp[i];
                if ( c < '0' || c > '9') {
                    break;
                }
                ss << c;
                i++;  
            } 
            ss >> value;
            values.push_back(value);
        }
        if (i >= exp.size()) break;

        if (c == ')') {
            while(ops.back() != '(') {
                pop_and_cal(values, ops);
            }
            ops.pop_back();
        } else if(c == '(') {
            ops.push_back(c);
        } else {
            while (ops.size() > 0 && prior[c] <= prior[ops.back()]) {
                pop_and_cal(values, ops);
            }
            ops.push_back(c);
        }
        i++;
    }
    while(ops.size() > 0) pop_and_cal(values, ops);
    return values.back();
}

int main() {
    string line;

    while(getline(cin, line)) {
        cout << cal(line) << endl;
    }
}