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; } }