227. 基本计算器 II
题目描述:
给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。
整数除法仅保留整数部分。
你可以假设给定的表达式总是有效的。所有中间结果将在 [-231, 231 - 1] 的范围内。
注意:不允许使用任何将字符串作为数学表达式计算的内置函数,比如 eval() 。
考察重点:计算加减乘除法(栈写法见 224. 基本计算器)
func findNum(nowPos int, s string) (int, int) { //寻找数字:"1+ 211 / 332" 发现数字或者乘除符号后,需要将整个数字字符串搜索完毕,并转为intstart := -1for ; nowPos < len(s); nowPos++ {if start == -1 && s[nowPos] >= '0' && s[nowPos] <= '9' { // start记录数字起始位置(因为可能有空格)start = nowPos}if start != -1 && (s[nowPos] < '0' || s[nowPos] > '9') { // 已经记录了起始位置,并且当前又一次发现非数字符号,停止遍历break}}nowNum, _ := strconv.Atoi(s[start:nowPos]) //将string转为intreturn nowNum, nowPos - 1 //遍历时,比如"234/1" nowPos会指向/,而下面循环中又会执行i++,导致switch跳过'/'号,所以需要nowPos-1
}/**
"-5 + 11 * 20 / 1"
——> opt变为-1
——> 5 * opt后,将-5压栈
——> opt变为1
——> 11 * opt后,将11压栈
——> 遇到*,弹出11,找到20,11*20后,将220压栈
——> 遇到/,弹出220,找到1,220/1后,将220压栈
——> 结束,遍历栈,结果为[-5,220] 相加得215
*/
func Calculate2(s string) int {res := 0stack := d.NewStack()nowOpt := 1preNum, nowNum := 0, 0for i := 0; i < len(s); i++ {switch s[i] {case ' ':continuecase '+':nowOpt = 1continuecase '-':nowOpt = -1continuecase '*':preNum = (*stack.Pop()).(int) //遇到乘除号,弹出上一个数字,即将乘除号前后的两数字做乘除,并将结果再次压栈nowNum, i = findNum(i, s)stack.Push(preNum * nowNum)continuecase '/':preNum = (*stack.Pop()).(int)nowNum, i = findNum(i, s)stack.Push(preNum / nowNum)continuedefault:nowNum, i = findNum(i, s)stack.Push(nowOpt * nowNum)continue}}for !stack.Empty() {res += (*stack.Pop()).(int)}return res
}