224. 基本计算器(困难)
题目描述:
给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。
注意:不允许使用任何将字符串作为数学表达式计算的内置函数,比如 eval()。
考察重点:使用go建立数据结构——栈。通过栈实现对字符串表达式中括号作用范围的判断。
type Item interface {
}
// Stack the stack of items
type Stack struct {
Items []Item
}
// New Create a new Stack
func NewStack() *Stack {
return &Stack{Items: []Item{}}
}
// Push adds an Item to the top of the stack
func (s *Stack) Push(t Item) {
s.Items = append(s.Items, t)
}
// Pop removes an Item from the top of the stack
func (s *Stack) Pop() *Item {
item := s.Items[len(s.Items)-1] // 后进先出
s.Items = s.Items[0 : len(s.Items)-1]
return &item
}
// Return an Item from the top of the stack
func (s *Stack) Top() *Item {
item := s.Items[len(s.Items)-1] // 后进先出
return &item
}
/**
符号之所以要入栈,是因为 1 - (2+3) - 5的这种情况,第一个‘-’只作用于(2+3) 而不作用于5,所以遇到')'就将'-'出栈
1 - (2 + (3 - 4) - 1)
遇到第一个(括号 - 入栈 作用范围(2 + (3 - 4) - 1)
遇到第二个(括号 + 入栈 作用范围(3 - 4)
遇到第一个)括号 + 出栈
遇到第二个)括号 - 出栈
*/
func Calculate(s string) int {
res := 0
stack := d.NewStack()
stack.Push(1)
opt := 1
for i := 0; i < len(s); {
switch s[i] {
case ' ':
i++
case '+':
opt = 1 * (*stack.Top()).(int)
i++
case '-':
opt = -1 * (*stack.Top()).(int)
i++
case '(':
stack.Push(opt)
i++
case ')':
stack.Pop()
i++
default:
start := i
for ; i < len(s) && s[i] >= '0' && s[i] <= '9'; i++ {
}
temp, _ := strconv.Atoi(s[start:i])
res += opt * temp
}
}
return res
}