1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
| #include <bits/stdc++.h>
using namespace std;
// 再帰下降パーサ
template<class T> struct Parser {
// results
int root; // vals[root] is the answer
vector<T> vals; // value of each node
vector<char> ops; // operator of each node ('a' means leaf values)
vector<int> left, right; // the index of left-node, right-node
vector<int> ids; // the node-index of i-th value
int ind = 0;
void init() {
vals.clear(); ops.clear(); left.clear(); right.clear(); ids.clear();
ind = 0;
}
// generate nodes
int newnode(char op, int lp, int rp, T val = 0) {
ops.push_back(op); left.push_back(lp); right.push_back(rp);
if (op == 'a') {
vals.push_back(val);
ids.push_back(ind++);
}
else {
if (op == '+') vals.push_back(vals[lp] + vals[rp]);
else if (op == '-') vals.push_back(vals[lp] - vals[rp]);
else if (op == '*') vals.push_back(vals[lp] * vals[rp]);
else if (op == '/') vals.push_back(vals[lp] / vals[rp]);
ids.push_back(-1);
}
return (int)vals.size() - 1;
}
// main solver
T solve(const string &S) {
int p = 0;
string nS = "";
for (auto c : S) if (c != ' ') nS += c;
root = expr(nS, p);
return vals[root];
}
// parser
int expr(const string &S, int &p) {
int lp = factor(S, p);
while (p < (int)S.size() && (S[p] == '+' || S[p] == '-')) {
char op = S[p]; ++p;
int rp = factor(S, p);
lp = newnode(op, lp, rp);
}
return lp;
}
int factor(const string &S, int &p) {
int lp = value(S, p);
while (p < (int)S.size() && (S[p]== '*' || S[p] == '/')) {
char op = S[p]; ++p;
int rp = value(S, p);
lp = newnode(op, lp, rp);
}
return lp;
}
int value(const string &S, int &p) {
if (S[p] == '(') {
++p; // skip '('
int lp = expr(S, p);
++p; // skip ')'
return lp;
}
else {
T val = 0;
int sign = 1;
if (p < (int)S.size() && S[p] == '-') sign = -1;
while (p < (int)S.size() && S[p] >= '0' && S[p] <= '9') {
val = val * 10 + (int)(S[p] - '0');
++p;
}
return newnode('a', -1, -1, val);
}
}
};
int main() {
Parser<int> parse;
cout << parse.solve("6 + 3") << endl;
cout << parse.solve("3 + (10 - 4) / 2") << endl;
cout << parse.solve("((6 - 3) * 2 + 10 / 5) * (-3)") << endl;
}
|