您的位置:首页 > 其它

leetcode -- Basic Calculator I &II --重点,未完全理解

2015-12-16 12:33 459 查看

Basic Calculator

https://leetcode.com/problems/basic-calculator/

此题目要求没有负号,所以降低了难度

思路1 转换成reverse polish,再使用stack

http://bookshadow.com/weblog/2015/06/09/leetcode-basic-calculator/

思路2 维护一个sign的stack就行

/article/4901785.html

这个效率高。不太好理解。看https://leetcode.com/discuss/39532/easy-18-lines-c-16-lines-python

def calculate(self, s):
total = 0
i, signs = 0, [1, 1]
while i < len(s):
c = s[i]
if c.isdigit():
start = i
while i < len(s) and s[i].isdigit():
i += 1
total += signs.pop() * int(s[start:i])
continue
if c in '+-(':
signs += signs[-1] * (1, -1)[c == '-'],
elif c == ')':
signs.pop()
i += 1
return total


思路3 用two stacks 求中缀表达式

/article/4719035.html

https://leetcode.com/discuss/39509/ac-c-solution-with-two-stacks

规则

- 规定左括号优先级最低,但是遇到左括号的时候不比较优先级直接Push

- 遇到右括号的时候,则要一直pop,并计算结果,push到operend stack,直到把左括号pop出来,

- 遇到其余operators, 则必须比较优先级,如果优先级大于栈顶元素才push否则计算operend stack 前两元素的结果

- 如果遇到负号,那么负号也看做operator,优先级最高。如果前一个字符为’)’或者数字的时候,是减号,其余都是负号。注意区分!

- 如果表达式scan完之后,operator的stack不为空,那么就从栈顶逐个pop计算结果push到operend stack,直到operator stack为空,剩下在operend的值就是结果

总的来说 operators 含有 +-*/以及负号,左右括号

思路4

左括号以及操作符入op stack,数字入num stack。遇到右括号就计算临时结果,这里用两个临时stacks将中缀转换成了后缀。计算完遇到右括号的结果之后,如果最后没有了括号,那么再做一次中缀转后缀就行。

code 用http://yucoding.blogspot.hk/2015/10/leetcode-question-basic-calculator.html

class Solution(object):

def compute(self, num, ops):
while len(ops) != 0:
op = ops.pop()
if op == '+':
num.append(num.pop() + num.pop())
else:
num.append(num.pop() - num.pop())
return num[-1]

def calculate(self, s):
"""
:type s: str
:rtype: int
"""
#remove spaces
s = s.replace(' ', '')#去掉space

#double stacks
num = []
ops = []

i = 0
n = ''
while i < len(s):
if s[i] >= '0' and s[i] <='9':#找到string s中的数字
n = n + s[i]
i += 1
else:
if n != '':#n为数字
num.append(int(n))
n = ''

if s[i] == ')':
tmp_num = []
tmp_ops = []
while ops[-1]!= '(':
#把num和ops中的元素倒置,因为 for expression 1-2+3, the output from stack is 3, 2, 1 and + , -,   3+2-1 is NOT equal to 1-2+3.
tmp_ops.append(ops.pop())
tmp_num.append(num.pop())
tmp_num.append(num.pop())#加上括号内离左括号最近的数
ops.pop()#pop掉左括号

num.append( self.compute(tmp_num, tmp_ops) )

else:
ops.append(s[i])

i += 1
#对于i scan到的最后一个操作数,表达式最末尾的操作数
if n!= '':
num.append(int(n))
#上面只有在遇到右括号的时候进行了表达式计算,这里对于剩下的没有括号的表达式进行计算。
tmp_num = []#这里相当于中缀转换为后缀
tmp_ops = []
while len(ops) != 0:
tmp_ops.append(ops.pop())
tmp_num.append(num.pop())
tmp_num.append(num.pop())

return self.compute(tmp_num, tmp_ops)


Basic Calculator II

也不要求考虑负号,降低了难度。

可以用上述的中缀表达式求值。

参考

http://yucoding.blogspot.hk/2015/10/leetcode-question-basic-calculator-ii.html

这里看ref里面的思路,很好理解。num[i]和num[i+1]对应ops[i]这个操作数,算出来的结果放到num[i]就行了。

class Solution(object):
def calculate(self, s):
"""
:type s: str
:rtype: int
"""

# remove spaces
s = s.replace(" ","")

num = [] # list of numbers
ops = [] # list of operators

# read numbers and operators from string
i = 0
n = ""
while i < len(s):
if '9'>= s[i] >= '0':
n = n + s[i]
else:
num.append(int(n))
n = ""
ops.append(s[i])
i+=1
if len(n) != 0:
num.append(int(n))

# compute all the * and / operations
i = 0
while i < len(ops):#这里十分巧妙,记住!
if ops[i] == '*':
num[i] = num[i] * num[i+1]
num.pop(i+1)
ops.pop(i)
elif ops[i] == '/':
num[i] = num[i] / num[i+1]
num.pop(i+1)
ops.pop(i)
else:
i += 1

# compute all the + and - operations
i = 0
while i < len(ops):
if ops[i] == '+':
num[i] = num[i] + num[i+1]
num.pop(i+1)
ops.pop(i)
elif ops[i] == '-':
num[i] = num[i] - num[i+1]
num.pop(i+1)
ops.pop(i)

return num[0]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: