其他分享
首页 > 其他分享> > 【字符串】力扣227:基本计算器 II

【字符串】力扣227:基本计算器 II

作者:互联网

给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。

整数除法仅保留整数部分。

你可以假设给定的表达式总是有效的。所有中间结果将在 [-231, 231 - 1] 的范围内。

注意:不允许使用任何将字符串作为数学表达式计算的内置函数,比如 eval() 。

示例:

输入:s = " 3+5 / 2 "
输出:5

注意:此类型题考察很多细节处理,如无运算符的情况,多个空格的情况等等。

重点:有 +, - ,*,/ 四种运算符;字符串中没有括号。

乘除优先于加减计算,所以不妨考虑先进行所有乘除运算,并将这些乘除运算后的整数值放回原表达式的相应位置,那么随后整个表达式的值,就等于一系列整数加减后的值。

如果在字符串左边加上一个加号(第一个数字左侧的运算符视为加号),可以证明其并不改变运算结果,且字符串可以分割成多个< 一个运算符,一个数字 >对子的形式;这样就可以从左往右处理字符串了。

可以用一个栈,保存这些(进行乘除运算后的)整数的值。即 先乘除再加减,用栈保存中间结果。

遍历完字符串 s 后,将栈中元素累加,即为该字符串表达式的值。

具体而言:

  1. 计算将要压入栈的数
    由于算式中可能出现两位数、三位数…… 这种连续数字字符串,而遍历字符串是处理完一个字符后再处理一个字符,此时就需要将连续数字字符转为整数,用变量 num 储存。

比如:字符串 ’23‘,num 第一次保存为2,num第二次保存 2 * 10 + 3 = 23

  1. 运算符与压栈
  1. 若读到一个运算符,或者遍历到字符串末尾,即认为是遍历到了数字末尾。处理完该数字后,更新运算符为当前遍历的字符。
class Solution:
    def calculate(self, s: str) -> int:
        n = len(s)
        stack = [] # 创建空栈,后续用append加入新元素
        op = '+' # 在第一个元素前加上加号
        num = 0 # 储存字符串中的数字
        for i, char in enumerate(s):
            if char.isdigit(): # 该元素是数字而不是运算符、空格或其他,主要为了排除空格干扰
                num = 10 * num + int(char) # 连续数字字符串转为数字
            if i == n - 1 or char in '+-*/':
                if op == '+':
                    stack.append(num) # 加号:将数字压入栈
                elif op == '-':
                    stack.append(-num) # 减号:将数字的相反数压入栈
                elif op == '*':
                    stack.append(stack.pop() * num) # 乘除号:计算数字与栈顶元素,并将栈顶元素替换为计算结果
                elif op =='/':
                    stack.append(int(stack.pop() / num)) # 切记整数化
                # 为下一次循环做准备,num 归零
                op = char
                num = 0
        return sum(stack) # 返回值为栈内储存值之和

时间复杂度:O(n),其中 n 为字符串 s 的长度。需要遍历字符串 s 一次,计算表达式的值。

空间复杂度:O(n),其中 n 为字符串 s 的长度。空间复杂度主要取决于栈的空间,栈的元素个数不超过 n。

标签:力扣,数字,运算符,乘除,II,字符串,num,227,stack
来源: https://www.cnblogs.com/Jojo-L/p/16437783.html