您的位置:首页 > 其它

[计蒜客 15504 百度的科学计算器(简单)]表达式求值

2017-05-21 21:43 239 查看

[计蒜客 15504 百度的科学计算器(简单)]表达式求值

分类:
Math
表达式求值


1. 题目链接

[计蒜客 15504 百度的科学计算器(简单)]

2. 题意描述

求一个只带加减的实数表达式。

注意,运算过程中可能会爆long long呢。

3. 解题思路

水题。贴一个精简版的表达式树模板。

4. 实现代码

#include <queue>
#include <stack>
#include <ctime>
#include <cmath>
#include <cctype>
#include <cstdio>
#include <string>
#include <cstring>
#include <cassert>
#include <iomanip>
#include <iostream>
#include <algorithm>

using namespace std;

typedef long long LL;
typedef long double LB;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
typedef vector<int> VI;

const int INF = 0x3f3f3f3f;
const LL INFL = 0x3f3f3f3f3f3f3f3fLL;
const long double PI = acos(-1.0);
const long double eps = 1e-6;
void debug() { cout << endl; }
template<typename T, typename ...R> void debug (T f, R ...r) { cout << "[" << f << "]"; debug (r...); }

const int MX = 1e5 + 5;
bool DIV_ZERO;
template<class T>struct Calc {
char op[MX];
int lch[MX], rch[MX], r;
T s[MX];
int build(char *S, int L, int R) {
int c[] = { -1, -1}, p = 0, u;
T sum = 0;
int dot_flag = false;
T dj = 1.0;
int sign = true;
for(int i = L; i <= R; i++) {
if(S[i] == '.') dot_flag = true, dj = 1.0;
else if(isdigit(S[i])) {
if(!dot_flag) sum = sum * 10 + S[i] - '0';
else dj *= 0.1, sum += dj * (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;
}
T solve(int u) {
if(op[u] == '.') return s[u];
T 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 (ar == 0 ? DIV_ZERO = 1, -1 : al / ar);
}
}
} ;
Calc<long long> int_calc;
Calc<long double> dbl_calc;

bool int_flag;
int n, len;
char expr[MX];

inline int sgn(double a, double b) {
if(fabs(a - b) < eps) return 0;
return a < b ? -1 : 1;
}

int main() {
#ifdef ___LOCAL_WONZY___
freopen ("input.txt", "r", stdin);
#endif // ___LOCAL_WONZY___
while(~scanf("%d", &n)) {
for(int i = 0; i < n; ++i) scanf("%*s");
scanf("%s", expr);
len = strlen(expr);
int_flag = true;
DIV_ZERO = false;
for(int i = 0; i < len; ++i) {
if(expr[i] == '.') int_flag = false;
}
if(int_flag) {
int u = int_calc.build(expr, 0, len - 1);
long long ans = int_calc.solve(u);
if(DIV_ZERO) puts("No Answer");
else printf("%lld\n", ans);
} else {
int u = dbl_calc.build(expr, 0, len - 1);
long double ans = dbl_calc.solve(u);
if(DIV_ZERO) puts("No Answer");
else printf("%.6f\n", (double)ans);
}
}
#ifdef ___LOCAL_WONZY___
cout << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC * 1000 << " ms." << endl;
#endif // ___LOCAL_WONZY___
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: