标签:
传送门:点击打开链接
题意:计算表达式,其中里面含有加减乘除括号
如果里面没有括号,那么使用栈简单维护一下即可
但是如果里面有括号了,或者有更复杂的运算符号,那么推荐使用表达式树来做
其实表达式树构造起来并没有想象中的那么麻烦,构造好之后直接分治算出答案即可
表达式树的核心思维就是找同优先级的最后一个运算符的位置,然后按照优先级递减顺序去考虑即可
#include<map> #include<set> #include<cmath> #include<stack> #include<queue> #include<cstdio> #include<string> #include<vector> #include<cstring> #include<iostream> #include<algorithm> #include<functional> #define FIN freopen("input.txt","r",stdin) #define FOUT freopen("output.txt","w+",stdout) using namespace std; typedef long long LL; typedef pair<int, int>PII; const int MX = 1e5 + 5; char op[MX]; int lch[MX], rch[MX], s[MX], r; int build(char *S, int L, int R) { int c[] = { -1, -1}, p = 0, u; int sum = 0, sign = true; for(int i = L; i <= R; i++) { if(isdigit(S[i])) sum = sum * 10 + S[i] - '0'; else { sign = false; break; } } if(sign) { u = ++r; op[u] = '.'; s[u] = sum; return u; } for(int i = L; i <= R; i++) { switch(S[i]) { case '(': p++; break; case ')': p--; break; case '+': case '-': if(!p) c[0] = i; break; case '*': case '/': if(!p) c[1] = i; break; } } if(c[0] < 0) c[0] = c[1]; if(c[0] < 0) u = build(S, L + 1, R - 1); else { u = ++r; op[u] = S[c[0]]; lch[u] = build(S, L, c[0] - 1); rch[u] = build(S, c[0] + 1, R); } return u; } double solve(int u) { if(op[u] == '.') return s[u]; double al = solve(lch[u]), ar = solve(rch[u]); switch(op[u]) { case '+': return al + ar; case '-': return al - ar; case '*': return al * ar; case '/': return al / ar; } } char S[MX]; int main() {//FIN; while(gets(S)) { r = 0; int len = strlen(S); int rt = build(S, 0, len - 1); printf("%.4lf\n", solve(rt)); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/qwb492859377/article/details/48026593