Basic Calculator I/II
要点:这类题无论怎么变化,都有基本模式:两个stack,一个ops,一个oprand。遇到oprand就push,遇到ops要分情况。
- ‘)’:括号里的结束。rewind or keep call computeAndPush
- ‘(’:just push
- ‘+-*/‘: 按优先级比较当前和ops.top(),while当前优先级低于ops.top()或者是'(',call computeAndPush
- 当前优先级低于ops.top:三种可能:ops.top()是/,或者按从左到右顺序,或者’(’。所以反过来低优先级只有一种可能,当前为/而ops.top为+-
leetcode的两题稍微简单一点:I只有+-(),而II只有+-*/
I
错误点:
- 什么时候push operand?如果等到下一个op,情况比较复杂,比如多个’)’会出错,所以计算数字的时候向前检查一个字符同时push
- 字符串添加’+’:因为loop内只有在下一个op的时候计算ops栈顶运算,添加’+’可以不用loop外再处理
- computeAndPush不用while loop,因为没有算符优先级,来一个算一个。
- ‘)’最后出栈’('
class Solution(object):
def calculate(self, s):
"""
:type s: str
:rtype: int
"""
def computeAndPush(ops, oprands):
op2 = oprands.pop()
op1 = oprands.pop()
op = ops.pop()
if op=='+':
oprands.append(op1+op2)
else:
oprands.append(op1-op2)
num = 0
ops = []
oprands = []
for i,ss in enumerate(s+'+'):
if ss==' ': continue
if ss.isdigit():
num = num*10+ord(ss)-ord('0')
if i+1==len(s) or not s[i+1].isdigit():
oprands.append(num)
num = 0
else:
if ss=='(':
ops.append('(')
else:
if ss==')':
if ops and ops[-1]!='(':
computeAndPush(ops, oprands)
ops.pop()
else:
if ops and ops[-1]!='(': computeAndPush(ops, oprands)
ops.append(ss)
#print oprands
#oprands.append(num)
#if ops: computeAndPush(ops, oprands)
return oprands[-1]
II
错误点:
- computeAndPush要用while loop,比如3+54-3:计算完后push-,ops中为[+,-]
- hasPrecedence:ops栈中的运算符是要求高优先级的,要注意顺序
class Solution(object):
def calculate(self, s):
"""
:type s: str
:rtype: int
"""
def computeAndPush(ops, oprands):
op2 = oprands.pop()
op1 = oprands.pop()
op = ops.pop()
# print op1,op2,op
if op=='+':
oprands.append(op1+op2)
elif op=='-':
oprands.append(op1-op2)
elif op=='*':
oprands.append(op1*op2)
elif op=='/':
oprands.append(op1/op2)
def hasPrecedence(op1, op2):
if op1 in '*/' and op2 in '+-': return False
return True
oprands = []
ops = []
num = 0
for i,ss in enumerate(s+'+'):
if ss==' ': continue
if ss.isdigit():
num=num*10+ord(ss)-ord('0')
if i+1==len(s) or not s[i+1].isdigit():
oprands.append(num)
num=0
else:
while ops and hasPrecedence(ss, ops[-1]):
computeAndPush(ops, oprands)
ops.append(ss)
# print oprands
return oprands[-1]