N - 秋实大哥搞算数
给一个表达式,无括号,保证合法,long long以内,整数运算,求值
栈 表达式求值的经典问题,
首先设置一个开始和结束符号#,他们的优先级是最低的,然后开两个栈,运算符栈和运算数栈,如果当前要放的运算符优先级高的话,就放进去,然后继续模拟,如果当前要放的运算符优先级低的话,就取出栈顶的运算符,和运算数栈顶的两个数,进行运算,然后继续检查,直到栈空或者栈顶运算符优先级低了为止,因为栈最先时放了一个#进去,所以保证合法,只有读入到结束符#时,运算符栈才会被算空
当然, 如果栈顶运算符和要加入的运算符相同,也是优先栈顶运算符计算的
end
代码:
#include <iostream> #include <vector> #include <cstring> #include <cstdio> #include <string> #include <algorithm> #include <vector> #include <stack> using namespace std; #define ll long long #define maxn 1000005 char str[maxn]; stack<char> oper; stack<ll> num; bool prior[5][5] = { { 1, 0, 0, 0, 0 }, { 1, 1, 1, 0, 0 }, { 1, 1, 1, 0, 0 }, { 1, 1, 1, 1, 1 }, { 1, 1, 1, 1, 1 } }; int idx(char c) { int x; switch (c) { case '#': x = 0; break; case '+': x = 1; break; case '-': x = 2; break; case '*': x = 3; break; case '/': x = 4; break; default: x = -1; break; } return x; } ll calcluate(ll a, ll b, char c) { ll ans; switch (c) { case '#': ans = b; break; case '+': ans = a + b; break; case '-': ans = a - b; break; case '*': ans = a*b; break; case '/': ans = a / b; break; } return ans; } int main(){ //freopen("input.txt", "r", stdin); int T; scanf("%d", &T); while (T--) { ll nn = 0; while (!num.empty()) num.pop(); while (!oper.empty()) oper.pop(); memset(str, 0, sizeof(char)*maxn); scanf("%s", str); oper.push('#'); int n = strlen(str); str[n++] = '#'; for (int i = 0; i < n; ++i) { if (str[i] >= '0'&&str[i] <= '9') { nn = nn * 10 + str[i] - '0'; } else { num.push(nn); nn = 0; int x = idx(str[i]); while (!oper.empty()) { char c = oper.top(); int y = idx(c); if (prior[y][x]) { oper.pop(); ll a = 0, b = 0; if (!num.empty()) { a = num.top(); num.pop(); } if (!num.empty()) { b = num.top(); num.pop(); } //printf("%d %lld %lld %c\n", i, b, a, c); num.push(calcluate(b, a, c)); } else { oper.push(str[i]); break; } } } } printf("%lld\n", num.top()); } //while (1); return 0; }