[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]

猜你喜欢

转载自www.cnblogs.com/journeyonmyway/p/12543808.html