• [LeetCode in Python] 224 (H) basic calculator 基本计算器


    题目:

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

    实现一个基本的计算器来计算一个简单的字符串表达式的值。
    字符串表达式可以包含左括号 ( ,右括号 ),加号 + ,减号 -,非负整数和空格  。

    示例 1:

    输入: "1 + 1"
    输出: 2

    示例 2:

    输入: " 2-1 + 2 "
    输出: 3

    示例 3:

    输入: "(1+(4+5+2)-3)+(6+8)"
    输出: 23

    说明:

    你可以假设所给定的表达式都是有效的。
    请不要使用内置的库函数 eval。

    解题思路

    • 本想使用FSM,后来发现也没有这个必要。
    • 运算符存在一个栈内,每个元素包含运算符及优先级,
    • 数字放在另一个栈内,方便起见,转为整形。
    • 每当看到"(",就将当前优先级+1,遇见")"就将优先级-1。
    • 将基础运算提炼为一个函数便于多次调用
    • 注意扫描到最后时,需要考虑数字是否都入栈了
    • 扫描完全部字符,需要挨个将运算符栈里的运算符弹出计算
    • 最后结果存在数字栈内,应该只剩一个了
    • 因为题目说明不会有无效情况,所以无需考虑异常case

    代码

    class Solution:
        def calculate(self, s: str) -> int:
            number = ''         # - current number
            level = 0           # - current op level
            number_stack = []   # - int number stack
            op_stack = []       # - element as (op,level)
    
            # - pop 2 numbers and 1 op, and do once calculate
            def calc_op():
                op, _ = op_stack.pop()
                right = number_stack.pop()
                left = number_stack.pop()
                
                if op == '+':
                    number_stack.append(left + right)
                elif op == '-':
                    number_stack.append(left - right)
                else:
                    pass
                    
            # - scan chars in s
            for c in s:
                if '0' <= c <= '9':
                    # - update number
                    number += c
                else:
                    # - push number in number_stack
                    if number:
                        number_stack.append(int(number))
                        number = ''
    
                    if c in ['+', '-']:
                        # - check operator level with op_stack[-1],
                        # - if current level is not greater than op in stack,
                        # - calculate the op in stack
                        while op_stack and (op_stack[-1][1] >= level):
                            calc_op()
    
                        # - push current op in op_stack
                        op_stack.append((c, level))
                    elif c == '(':
                        level += 1
                    elif c == ')':
                        level -= 1
                    else:
                        pass
            
            # - if end with number
            if number:
                number_stack.append(int(number))
    
            # - check if still has op to calc
            while op_stack:
                calc_op()
    
            return number_stack[0]
    
  • 相关阅读:
    Javascript、Jquery获取浏览器和屏幕各种高度宽度
    Chrome浏览器快捷键
    CSS流体(自适应)布局下宽度分离原则
    JS中的call()和apply()方法
    获取滚动条高度
    手把手教你写Sublime中的Snippet
    Ajax
    javascript创建文档碎片节点
    JS获取元素尺寸大小、鼠标位置
    web开发必备插件
  • 原文地址:https://www.cnblogs.com/journeyonmyway/p/12543808.html
Copyright © 2020-2023  润新知