-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathStack
More file actions
42 lines (42 loc) · 1.52 KB
/
Copy pathStack
File metadata and controls
42 lines (42 loc) · 1.52 KB
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
public int evaluate(String expression) {
return eval(expression, new HashMap<>());
}
private int eval(String exp, Map<String, Integer> parent) {
if (exp.charAt(0) != '(') {
// just a number or a symbol
if (Character.isDigit(exp.charAt(0)) || exp.charAt(0) == '-')
return Integer.parseInt(exp);
return parent.get(exp);
}
// create a new scope, add add all the previous values to it
Map<String, Integer> map = new HashMap<>();
map.putAll(parent);
List<String> tokens = parse(exp.substring(exp.charAt(1) == 'm' ? 6 : 5, exp.length() - 1));
if (exp.startsWith("(a")) { // add
return eval(tokens.get(0), map) + eval(tokens.get(1), map);
} else if (exp.startsWith("(m")) { // mult
return eval(tokens.get(0), map) * eval(tokens.get(1), map);
} else { // let
for (int i = 0; i < tokens.size() - 2; i += 2)
map.put(tokens.get(i), eval(tokens.get(i + 1), map));
return eval(tokens.get(tokens.size() - 1), map);
}
}
private List<String> parse(String str) {
// seperate the values between two parentheses
List<String> res = new ArrayList<>();
int par = 0;
StringBuilder sb = new StringBuilder();
for (char c: str.toCharArray()) {
if (c == '(') par++;
if (c == ')') par--;
if (par == 0 && c == ' ') {
res.add(new String(sb));
sb = new StringBuilder();
} else {
sb.append(c);
}
}
if (sb.length() > 0) res.add(new String(sb));
return res;
}