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

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就行

http://www.cnblogs.com/grandyang/p/4570699.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 求中缀表达式

http://www.cnblogs.com/dolphin0520/p/3708602.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]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
LeetCode-Editor是一种在线编码工具,它提供了一个用户友好的界面编写和运行代码。在使用LeetCode-Editor时,有时候会出现乱码的问题。 乱码的原因可能是由于编码格式不兼容或者编码错误导致的。在这种情况下,我们可以尝试以下几种解决方法: 1. 检查文件编码格式:首先,我们可以检查所编辑的文件的编码格式。通常来说,常用的编码格式有UTF-8和ASCII等。我们可以将编码格式更改为正确的格式。在LeetCode-Editor中,可以通过界面设置或编辑器设置来更改编码格式。 2. 使用正确的字符集:如果乱码是由于使用了不同的字符集导致的,我们可以尝试更改使用正确的字符集。常见的字符集如Unicode或者UTF-8等。在LeetCode-Editor中,可以在编辑器中选择正确的字符集。 3. 使用合适的编辑器:有时候,乱码问题可能与LeetCode-Editor自身相关。我们可以尝试使用其他编码工具,如Text Editor、Sublime Text或者IDE,看是否能够解决乱码问题。 4. 查找特殊字符:如果乱码问题只出现在某些特殊字符上,我们可以尝试找到并替换这些字符。通过仔细检查代码,我们可以找到导致乱码的特定字符,并进行修正或替换。 总之,解决LeetCode-Editor乱码问题的方法有很多。根据具体情况,我们可以尝试更改文件编码格式、使用正确的字符集、更换编辑器或者查找并替换特殊字符等方法来解决这个问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值