当前位置:   article > 正文

leetcode-227. 基本计算器 II_基本计算器 leetcode

基本计算器 leetcode

题目

实现一个基本的计算器来计算一个简单的字符串表达式的值。

字符串表达式仅包含非负整数,+, - ,*,/ 四种运算符和空格 。 整数除法仅保留整数部分。

示例 1:

输入: "3+2*2"
输出: 7
  • 1
  • 2

示例 2:

输入: " 3/2 "
输出: 1
  • 1
  • 2

示例 3:

输入: " 3+5 / 2 "
输出: 5
  • 1
  • 2

解题思路

Consider - as negative numbers

说是栈的经典应用,结果好难做,哭哭

最基本的题目,参考了这篇题解:https://leetcode-cn.com/problems/basic-calculator-ii/solution/chai-jie-fu-za-wen-ti-shi-xian-yi-ge-wan-zheng-ji-/

首先讨论只有+, -的情况,对于每个数,用sign来表示这个数字之前的符号,然后碰到新的符号后,就把之前的带符号数字入栈,然后根据字符串中的符号,更新每个数字前的符号。这样做的意义是,把减法变成了数字内部的,最后可以直接求所有栈内数字的总和. Similar to word count in MapReduce.

如果增加了*, /符号,那么上面的做法有一点就不行了,不能在最后求栈内数字的总和了。又因为,*, /的优先级比+, -要高,所以可以稍作修改:当发现当前数字前面的符号是*, /时,就先运算一下(用此时栈顶的元素和当前元素做运算),然后把运算结果加入到栈里面。最后同样地求栈内总和即可。

Time complexity: o ( n ) o(n) o(n)
Space complexity: o ( n ) o(n) o(n)


Intuitive

If it’s * or /, then calculate and put the result into stack. Otherwise put the number into stack. After preprocessing, the stack only contains numbers and +, -, and looks like: num1, +, num2, -, num3, ...
Go through the stack again to calculate the + and -.

Time complexity: o ( n ) o(n) o(n)
Space complexity: o ( n ) o(n) o(n)

代码

Intuitive

class Solution:
    def calculate(self, s: str) -> int:
        def read_number(s: str, index: int) -> tuple:
            """
            Read number
            Returns:
                number: int
                new_i: new index
            """
            number = 0
            while index < len(s) and s[index].isdigit():
                number = number * 10 + int(s[index])
                index += 1
            return number, index

        stack = []
        i = 0
        while i < len(s):
            if s[i].isdigit():
                number, i = read_number(s, i)
                if stack and stack[-1] in ('*', '/'):
                    op, num1 = stack.pop(), stack.pop()
                    if op == '*':
                        stack.append(number * num1)
                    elif op == '/':
                        stack.append(num1 // number)
                else:
                    stack.append(number)
            elif s[i] in ('+', '-', '*', '/'):
                stack.append(s[i])
                i += 1
            else:
                i += 1
        res = 0
        for i in range(2, len(stack), 2):
            num1, op, num2 = stack[i - 2], stack[i - 1], stack[i]
            if op == '+':
                res = num1 + num2
            elif op == '-':
                res = num1 - num2
            stack[i] = res
        return stack[-1]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

Consider - as negative numbers

class Solution:
    def calculate(self, s: str) -> int:
        stack = []
        op, sign = 0, '+'
        s += '+0'
        for ch in s:
            if ch.isdecimal():
                op = op * 10 + int(ch)
            elif ch == '+' or ch == '-' or ch == '*' or ch == '/':
                if sign == '+' or sign == '-':
                    stack.append(op * (1 if sign == '+' else -1))
                elif sign == '*':
                    stack[-1] *= op
                elif sign == '/':
                    stack[-1] = int(stack[-1] / op)
                op = 0
                sign = ch
        return sum(stack)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

扩展

如果是带括号的计算器的话,就用递归计算括号内的内容。递归的时候需要对原输入做改变,比如计算"3 * (1 - 2) + 3 / (2 - 1)"时,对(1 - 2)递归后,下一次应该从+开始了,所以传入一个list并且用pop的方式来访问list内的元素

加了对括号的处理,代码如下:

class Solution:
    def calculate(self, s: str) -> int:
        def helper(s: collections.deque) -> int:
            ans, op = 0, 0
            sign = '+'
            stack = []
            while s:
                ch = s.popleft()
                if ch.isdecimal():
                    op = op * 10 + int(ch)
                elif ch == '+' or ch == '-' or ch == '*' or ch == '/':
                    if sign == '+' or sign == '-':
                        stack.append(op * (1 if sign == '+' else -1))
                    elif sign == '*':
                        stack[-1] *= op
                    elif sign == '/':
                        stack[-1] = int(stack[-1] / op)
                    op = 0
                    sign = ch
                elif ch == '(':
                    op = helper(s)
                elif ch == ')':
                    if sign == '+' or sign == '-':
                        stack.append(op * (1 if sign == '+' else -1))
                    elif sign == '*':
                        stack[-1] *= op
                    elif sign == '/':
                        stack[-1] = int(stack[-1] / op)
                    break
            return sum(stack)
        return helper(collections.deque(s + '+0'))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号