题目:
给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。
注意:不允许使用任何将字符串作为数学表达式计算的内置函数,比如 eval() 。
解法:
方法一:跌跌撞撞法
总体思路是:遍历s到非数字时,将num乘以上一个符号,放入stack中,最后对stack的数字求和:
- ( 2 + ( 1 - 4 ))
⬆求和
遍历到‘)’时,括号内会得到一个数字
边界条件: 1、str遍历结束时会得到一个数字
func calculate(s string) int {
stack := make([]int, 0)
leftBraketStack := make([]int, 0)
opStack := make([]byte, 0)
lastOP := byte('+')
num := 0
for i := range s {
if '0' <= s[i] && s[i] <= '9' {
num = num * 10 + int(s[i] - '0')
} else if s[i] != ' ' {
if lastOP == '-' {
num = -1 * num
}
stack = append(stack, num)
// fmt.Println(i, stack)
num = 0
if s[i] == '(' {
opStack = append(opStack, lastOP)
lastOP = byte('+')
leftBraketStack = append(leftBraketStack, len(stack))
} else if s[i] == '+' || s[i] == '-' {
lastOP = s[i]
} else if s[i] == ')' {
// 找到最近的(开始的位置立即开始计算
leftBraket := leftBraketStack[len(leftBraketStack) - 1]
leftBraketStack = leftBraketStack[:len(leftBraketStack) - 1]
sum := 0
for start := leftBraket; start < len(stack); start ++ {
sum = sum + stack[start]
}
lastOP = opStack[len(opStack) - 1]
opStack = opStack[:len(opStack) - 1]
if lastOP == '-' {
sum = -1 * sum
}
stack[leftBraket] = sum
stack = stack[:leftBraket + 1]
}
}
if i == len(s) - 1 {
if lastOP == '-' {
num = -1 * num
}
stack = append(stack, num)
}
}
ans := 0
for i := range stack {
ans = ans + stack[i]
}
return ans
}
方法二:
func calculate(s string) int {
nums := make([]int, 0)
ops := make([]int, 1)
ops[0] = 1
ans, num, sign := 0, 0, 1
for i := range s {
if '0' <= s[i] && s[i] <= '9' {
num = num * 10 + int(s[i] - '0')
} else if s[i] == '+' {
ans = ans + num * sign
sign = 1
num = 0
} else if s[i] == '-' {
ans = ans + num * sign
sign = -1
num = 0
} else if s[i] == '(' {
// 注意这里是保存ans
nums = append(nums, ans)
ops = append(ops, sign)
ans = 0
sign = 1
} else if s[i] == ')' {
ans = ans + sign * num
ans = nums[len(nums) - 1] + ans * ops[len(ops) - 1]
nums = nums[:len(nums) - 1]
ops = ops[:len(ops) - 1]
sign = 1 // )后面必然跟+,-,这里可以不写
num = 0
}
}
ans = ans + sign * num
return ans
}