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

来源:互联网 发布:java泛型t 编辑:程序博客网 时间:2024/05/21 17:01

[计蒜客 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;}
阅读全文
1 0