优先级
乘除 > 加减 > 左括号( > 右括号)
计算过程
维护一个操作数栈,一个操作符栈。
每次遇到一个数字或 ‘(‘ 压栈。
对于 +-*/ 符号,如果当前符号优先级小于等于栈顶符号,则进行计算,弹出栈顶,直到优先级大于栈顶符号,将当前符号压栈。
对于 ) 符号,不断出栈计算,直到遇到第一个 (。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
| #include <cstdio> #include <cstring> #include <algorithm> #include <stack> #define ms(a,b) memset(a,b,sizeof(a)) using namespace std; typedef long long ll; const int maxn = 100000 + 5;
char s[maxn];
int get(char ch){ if (ch == '+' || ch == '-') return 1; if (ch == '*' || ch == '/') return 2; if (ch == '(') return 0; return -1; } int cmp(char x, char y){ return get(x) <= get(y); }
double cal(){ stack<double> num; stack<char> ope; int len = strlen(s); double ans = 0; for (int i = 0; i < len; i++){ if (s[i] >= '0' && s[i] <= '9') num.push(double(s[i] - '0')); else{ if (s[i] == '(') { ope.push(s[i]); continue; } int flag = 0; while (!ope.empty() && cmp(s[i], ope.top())){ char ch = ope.top(); if (s[i] == ')'){ if (flag) break; if (ch == '(') flag = 1; } ope.pop(); if (ch == '*'){ double x = num.top(); num.pop(); double y = num.top(); num.pop(); num.push(x * y); } if (ch == '/'){ double x = num.top(); num.pop(); double y = num.top(); num.pop(); num.push(y / x); } if (ch == '+'){ double x = num.top(); num.pop(); double y = num.top(); num.pop(); num.push(x + y); } if (ch == '-'){ double x = num.top(); num.pop(); double y = num.top(); num.pop(); num.push(y - x); } } if (s[i] != ')') ope.push(s[i]); } } return ans = num.top(); }
int main(){ int T; scanf("%d", &T); while (T--){ scanf("%s", s + 1); int len = strlen(s + 1); s[0] = '(', s[len + 1] = ')'; s[len + 2] = '\0'; printf("%.2lf\n", cal()); } return 0; }
|