-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcal.js
133 lines (119 loc) · 2.71 KB
/
cal.js
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
var log = console.log.bind(console)
var tokenize = function(s){
var tokens = []
var num = ''
for(var i=0; i<s.length; i++) {
var e = s[i]
if(e === ' ') {
continue
} else if(isSymbol(e)) {
tokens.push(e)
} else if(isNum(e)) {
num += e
if (i+1 === s.length && num != '') { // e为最后一个字符
tokens.push(parseInt(num))
num = ''
}
var next = s[i+1]
if (!isNum(next) && num != '') { // e的下一个字符不为数字字符
tokens.push(parseInt(num))
num = ''
}
} else {
log('error')
break
}
}
return tokens
}
var evalExpr = function(tokens) {
if(tokens.length == 1) {
var token = tokens[0]
if(isArray(token)) {
return evalExpr(token)
} else {
return token
}
}else{
var sign = ''
var cutIndex = 0
for(var i=0; i<tokens.length; i++) {
token = tokens[i]
if (token == '+' || token == '-') {
sign = token
cutIndex = i
break
}
if (token == '*' || token == '/') {
sign = token
cutIndex = i
continue
}
}
var left = cutLeft(tokens, cutIndex)
var right = cutRight(tokens, cutIndex)
switch(sign) {
case '+':
return evalExpr(left) + evalExpr(right)
case '-':
return evalExpr(left) - evalExpr(right)
case '*':
return evalExpr(left) * evalExpr(right)
case '/':
return evalExpr(left) / evalExpr(right)
}
}
}
var cutLeft = function(tokens, cutIndex) {
return tokens.slice(0, cutIndex)
}
var cutRight = function(tokens, cutIndex) {
return tokens.slice(cutIndex+1, tokens.length)
}
var isNum = function(e) {
return '.0123456789'.includes(e)
}
var isSymbol = function(e) {
return e === '(' || e === ')' || e === '+' || e === '-' || e === '*' || e === '/'
}
var isArray = function(e) {
return Array.isArray(e)
}
var makeTree = function(tokens) {
var skips = 0
var ret = {
tree: [],
count: 0
}
for(var i=0; i<tokens.length; i++) {
var e = tokens[i]
ret.count ++
if(skips > 0) {
skips --
continue
}
if (e === ')') {
return ret
} else if( e === '(') {
var right = cutRight(tokens, i)
var sub = makeTree(right)
ret.tree.push(sub.tree)
skips = sub.count
} else {
ret.tree.push(e)
}
}
return ret
}
var cal = function(s) {
var tokens = tokenize(s)
var tree = makeTree(tokens).tree
return evalExpr(tree)
}
var __main = function() {
res1 = cal('6 + 3 * 5 + 6 * 2 + (5 + 6)*5+8*(2 + 3*(4 + 2*4))') === (6 + 3 * 5 + 6 * 2 + (5 + 6)*5+8*(2 + 3*(4 + 2*4)))
log(res1)
res2 = cal('2 + 5 + (6 - 3) * 2') === (2 + 5 + (6 - 3) * 2)
log(res2)
}
__main()