# 加减乘除带括号
定义结果字段res, 原理是相加”a + b“, 如果是b是负数 那么 a+(-b)
s 为要遍历的字符串,尾部加”+“
遍历前定义上一次的操作符pos为1,也就是”+“
遍历到数字的时候,定义subStr子串,代表上一次的保存的值
首先只考虑加减的时候,遍历到操作符的时候,只要把上一次的操作符pos和subStr相乘,得到数字和res相加,把pos设为当前操作符,subStr设为”“
有了乘除,要考虑优先级,如果碰到*/,就把subStr和pos存储起来,等下一次再遇到操作符的时候取出计算后重新赋值subStr,再按照加减的算法继续
有括号的情况,用递归,如果遇到左括号,继续循环,直到遇到最后一个右括号,这中间的字符串取出,赋值subStr,比如 5+(8-9*(2-1)), 8-9*(2-1)作为新的字符串计算
function caculator(s) {
s = s + '+'
let res = 0 // 结果
let subStr = ''
let pos = 1 // 上一次的操作符
let tempData = [] // 存储上一次的 subStr 和 操作符
let zuokuoArr = [] // 左括号栈
let num = 0 // 配合 左括号栈 匹配到右括号时子串长度
let i = 0
for (i; i < s.length; i++) {
var ch = s.charAt(i)
// 如果碰到左括号,左括号栈 入栈
if (ch === '(') {
zuokuoArr.push('(')
}
// 如果碰到右括号,左括号栈 出栈
if (ch === ')') {
zuokuoArr.pop()
}
// 如果左括号栈内还有左括号,继续循环,子串长度 + 1
if (zuokuoArr.length > 0) {
num++
continue
}
// 如果发现左括号栈 长度为0 并且 有子串, 那么递归单独计算子串,把结果赋值给subStr, 子串长度设为0,继续循环
if (zuokuoArr.length === 0 && num > 0) {
const t = s.substring(i - num + 1, i)
num = 0
subStr = caculator(t)
continue
}
/////////////////// 以上是括号逻辑 ////////////////////
////////////////// 下面是计算逻辑 ////////////////////
// 如果发现 是数字,继续循环,得到完整数字
if (ch >= 0 && ch <= 9) {
subStr = subStr + ch
continue
}
// 如果碰到 +-*/
if (['+', '-', '*', '/'].includes(ch)) {
// 先判断前面的是否存储上一次的subStr, 计算得出当前subStr
if (tempData.length > 0) {
const op = tempData.pop()
const d = tempData.pop()
if (op === '*') {
subStr = d * subStr
} else if (op === '/') {
subStr = d / subStr
}
}
// 如果是 + - ,计算结果,如果是*/,存储subStr和操作符
switch (ch) {
case '+':
res += pos * subStr
subStr = ''
pos = 1
break
case '-':
res += pos * subStr
subStr = ''
pos = -1
break
case '*':
tempData.push(subStr)
tempData.push(ch)
subStr = ''
break
case '/':
tempData.push(subStr)
tempData.push(ch)
subStr = ''
break
default:
break
}
}
}
return res
}
console.log(caculator('4-4*(3+2)-(4)+4'))
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
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