标签:
传送门:点击打开链接
题意:计算表达式,其中里面含有加减乘除括号
如果里面没有括号,那么使用栈简单维护一下即可
但是如果里面有括号了,或者有更复杂的运算符号,那么推荐使用表达式树来做
其实表达式树构造起来并没有想象中的那么麻烦,构造好之后直接分治算出答案即可
表达式树的核心思维就是找同优先级的最后一个运算符的位置,然后按照优先级递减顺序去考虑即可
#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