224. 基本计算器
题目链接
描述
实现一个基本的计算器来计算一个简单的字符串表达式
s
的值。
示例
示例 1:
输入:s = “1 + 1”
输出:2
示例 2:输入:s = " 2-1 + 2 "
输出:3
示例 3:输入:s = “(1+(4+5+2)-3)+(6+8)”
输出:23
提示
1 <= s.length <= 3 * 105
s
由数字、'+'
、'-'
、'('
、')'
、和' '
组成s
表示一个有效的表达式
分析
由于只有+,-运算,所以可以想到去括号的形式
设置一个标记为sign,sign表示当前的运算应该是+还是-
有一个栈opt维护小括号,当存在小括号的时候,小括号里面的运算符依赖于小括号前的sign
代码
方式一:通过switch
func calculate(s string) (ret int) {
// 决定当前是+还是-
sign := 1
n := len(s)
// 操作数栈 一开始是+的
opt := make([]int, n)
opt[0] = 1
// top为栈顶标记
top := 0
for i := 0; i < n; {
switch s[i] {
case ' ':
i++
case '+':
sign = opt[top]
i++
case '-':
sign = -opt[top]
i++
case '(':
// 判断括号前的符号
top++
opt[top] = sign
i++
case ')':
top--
i++
default:
// 数值直接运算, 注意数值可能有多位,循环取值
num := 0
for ; i <n && s[i] <= '9' && s[i] >= '0'; i++ {
num = num * 10 + int(s[i]) - '0'
}
ret += num*sign
}
}
return
}
方式二:不使用switch,使用map记录操作
func calculate(s string) (ret int) {
// 决定当前是+还是-
sign := 1
n := len(s)
// 操作数栈 一开始是+的
opt := make([]int, n)
opt[0] = 1
// top为栈顶标记
top := 0
i := 0
tagMap := map[uint8]func(){
' ': func() {
},
'+': func() {
sign = opt[top]
},
'-': func() {
sign = -opt[top]
},
'(': func() {
// 判断括号前的符号
top++
opt[top] = sign
},
')': func() {
top--
},
}
for i < n {
do, ok := tagMap[s[i]]
// 数值直接运算, 注意数值可能有多位,循环取值
if ok {
do()
i++
} else {
num := 0
for ; i < n && s[i] <= '9' && s[i] >= '0'; i++ {
// v := int(s[i]) - '0'
num = num*10 + int(s[i]) - '0'
}
ret += num * sign
}
}
return
}