• 边工作边刷题:70天一遍leetcode: day 63-1


    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]
            
    
  • 相关阅读:
    CSS截断字符串
    [VB.NET] 打印DataGridView类
    [C#] 打印DataGridView类
    [MySQL] errno:150
    [C#] 用户自定义控件(含源代码)透明文本框
    [分享] 微软面试题
    [C#] 用户自定义控件(含源代码)圆角Panel
    [MySQL] 史上最全的MySQL备份方法
    [C#(WebForm)] 利用递归遍历文件夹和文件存入TreeView
    [VB] (开源)VB高仿Windows7桌面炫丽版
  • 原文地址:https://www.cnblogs.com/absolute/p/5690345.html
Copyright © 2020-2023  润新知