namespace cal_expression{
int level[300];
bool f;
///设置优先级
inline void init() {
level['*'] = level['/'] = 2;
level['+'] = level['-'] = 1;
f = true;
}
///加空格
inline string add_blank(string s) {
string t;
for (int i = 0; i < s.size(); ++i) {
if(isdigit(s[i])) t += s[i];
else {
t += ' ';
t += s[i];
t += ' ';
}
}
return t;
}
inline string convert(string s) { // 把中缀表达式转换为后缀表达式
stack<char> oper;
stringstream ss;
ss << s;
string t, tmp;
while (ss >> tmp) {
if (isdigit(tmp[0]))
t += tmp + " "; // 1. 如果遇到一个数,输出该数
else if (tmp[0] == '(')
oper.push(tmp[0]); // 2. 如果遇到左括号,把左括号入栈
else if (tmp[0] == ')') { // 3. 如果遇到右括号,
while (!oper.empty() && oper.top() != '(')
t += string(1, oper.top()) + " ",
oper.pop(); // 不断取出栈顶并输出,直到栈顶为左括号,
oper.pop(); // 然后把左括号出栈
} else { // 4. 如果遇到运算符
while (!oper.empty() && level[oper.top()] >= level[tmp[0]])
t += string(1, oper.top()) + " ",
oper.pop(); // 只要栈顶符号的优先级不低于新符号,就不断取出栈顶并输出
oper.push(tmp[0]); // 最后把新符号进栈
}
}
while (!oper.empty()) t += string(1, oper.top()) + " ", oper.pop();
return t;
}
inline int calc(string s) { // 计算转换好的后缀表达式
stack<int> num;
stringstream ss;
ss << s;
string t, tmp;
while (ss >> tmp) {
if (isdigit(tmp[0]))
num.push(stoi(tmp));
else {
int b, a; // 取出栈顶元素,注意顺序
if (!num.empty()) b = num.top();
num.pop();
if (!num.empty()) a = num.top();
num.pop();
if (tmp[0] == '+') num.push(a + b);
if (tmp[0] == '-') num.push(a - b);
if (tmp[0] == '*') num.push(a * b);
if (tmp[0] == '/') {
if(b && a%b == 0) num.push(a / b);
else num.push(555), f = false;
}
}
}
return num.top();
}
inline int solve(string s) {
init();
int v = calc(convert(add_blank(s)));
if(f) return v;
else return -1;
}
}