|
1 | 1 | package Problem0736
|
2 | 2 |
|
3 |
| -import ( |
4 |
| - "strconv" |
5 |
| - "strings" |
6 |
| -) |
| 3 | +import "strconv" |
7 | 4 |
|
8 | 5 | func evaluate(expression string) int {
|
9 |
| - expression = strings.Replace(expression, "(", "( ", -1) |
10 |
| - expression = strings.Replace(expression, ")", " )", -1) |
11 | 6 | return helper(expression, nil)
|
12 | 7 | }
|
13 | 8 |
|
14 | 9 | func helper(exp string, s *scope) int {
|
15 | 10 | if exp[0] != '(' {
|
16 | 11 | num, err := strconv.Atoi(exp)
|
17 |
| - if err == nil { |
18 |
| - return num |
| 12 | + if err != nil { |
| 13 | + return s.get(exp) |
19 | 14 | }
|
20 |
| - return s.get(exp) |
| 15 | + return num |
21 | 16 | }
|
22 | 17 |
|
23 |
| - // 删除最外层的 "( " 和 " )" |
24 |
| - exp = exp[2 : len(exp)-2] |
25 |
| - es := split(exp) |
26 |
| - switch es[0] { |
| 18 | + // 删除外层的 "()" |
| 19 | + exp = exp[1 : len(exp)-1] |
| 20 | + var keyWord string |
| 21 | + keyWord, exp = split(exp) |
| 22 | + switch keyWord { |
27 | 23 | case "add":
|
28 |
| - return helper(es[1], s) + helper(es[2], s) |
| 24 | + a, b := split(exp) |
| 25 | + return helper(a, s) + helper(b, s) |
29 | 26 | case "mult":
|
30 |
| - return helper(es[1], s) * helper(es[2], s) |
| 27 | + a, b := split(exp) |
| 28 | + return helper(a, s) * helper(b, s) |
31 | 29 | default:
|
| 30 | + // 遇到 let 就意味着要生成新的 scope 了 |
32 | 31 | s = newScope(s)
|
33 |
| - var i int |
34 |
| - for i = 1; i < len(es)-2; i += 2 { |
35 |
| - s.add(es[i], helper(es[i+1], newScope(s))) |
| 32 | + var key, val string |
| 33 | + for { |
| 34 | + key, exp = split(exp) |
| 35 | + if exp == "" { |
| 36 | + break |
| 37 | + } |
| 38 | + val, exp = split(exp) |
| 39 | + s.add(key, helper(val, s)) |
36 | 40 | }
|
37 |
| - return helper(es[i], s) |
| 41 | + return helper(key, s) |
38 | 42 | }
|
39 |
| - |
40 | 43 | }
|
41 | 44 |
|
42 |
| -func split(exp string) []string { |
43 |
| - ss := strings.Split(exp, " ") |
44 |
| - countLeft := 0 |
45 |
| - res := make([]string, 0, len(ss)) |
46 |
| - for _, s := range ss { |
47 |
| - if countLeft == 0 { |
48 |
| - res = append(res, s) |
49 |
| - } else { |
50 |
| - res[len(res)-1] += " " + s |
| 45 | +// split 把 exp 分割成 pre 和 post |
| 46 | +// 其中 pre 是 exp 中的第一个独立的块,post 则是剩下的部分 |
| 47 | +// 比如 |
| 48 | +// exp = "add 1 2" |
| 49 | +// 则 |
| 50 | +// pre = "add" |
| 51 | +// post = "1 2" |
| 52 | +// 又比如 |
| 53 | +// exp = "(add x1 (add x2 x3))" |
| 54 | +// 则 |
| 55 | +// pre = "(add x1 (add x2 x3))" |
| 56 | +// post = "" |
| 57 | +func split(exp string) (pre, post string) { |
| 58 | + n := len(exp) |
| 59 | + i := 0 |
| 60 | + if exp[0] == '(' { |
| 61 | + countLeft := 0 |
| 62 | + for i < n { |
| 63 | + if exp[i] == '(' { |
| 64 | + countLeft++ |
| 65 | + } else if exp[i] == ')' { |
| 66 | + countLeft-- |
| 67 | + } |
| 68 | + if countLeft == 0 { |
| 69 | + break |
| 70 | + } |
| 71 | + i++ |
51 | 72 | }
|
52 |
| - if s == "(" { |
53 |
| - countLeft++ |
54 |
| - } else if s == ")" { |
55 |
| - countLeft-- |
| 73 | + } else { |
| 74 | + for i+1 < n { |
| 75 | + if exp[i+1] == ' ' { |
| 76 | + break |
| 77 | + } |
| 78 | + i++ |
56 | 79 | }
|
57 | 80 | }
|
58 | 81 |
|
59 |
| - return res |
| 82 | + pre = exp[:i+1] |
| 83 | + if i+1 == n { |
| 84 | + post = "" |
| 85 | + } else { |
| 86 | + post = exp[i+2:] |
| 87 | + } |
| 88 | + |
| 89 | + return |
60 | 90 | }
|
61 | 91 |
|
62 | 92 | type scope struct {
|
|
0 commit comments