采用双栈解题

建立两个栈

  • number_stack:存放字符串s中的数字

  • sign_stack:存放字符串中的括号,运算符

遍历字符串,将字符串中表示数字和符号的部分分别压入数字栈和符号栈中。

压入数字栈的时候,如数字123,遍历字符串依次得到"1","2","3",故需要对相应的数字乘以相应的位数转化为对应的数值1×10×10+2×10+3。

压入符号栈的时候,规则如下:

  1. 判断左括号,压入符号栈
  2. 判断右括号,计算与之匹配的左括号之间的数值运算,并将结果压入数字栈中
  3. 判断乘号,当符号栈为空的时候,直接压入符号栈;符号栈非空,且栈顶为号,弹出数字栈顶两个数字,与符号栈顶符号,进行运算,结果压入数字栈中;符号栈非空,且栈顶不为号。(此时对应一个括号内的公式,只含+-,优先级低于乘法)。
  4. 判断加减,符号栈为空,直接压入;符号栈非空,栈顶为运算符,弹出数字栈顶两个数字,与符号栈顶符号,进行运算,结果压入数字栈中(即计算此前括号内公式);符号栈非空,栈顶不为运算符,直接压入栈中。
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 返回表达式的值
# @param s string字符串 待计算的表达式
# @return int整型
#
class Solution:
    def solve(self, s: str) -> int:
        # write code here
        # 表达式的计算函数
        def computer(first, last, sign):
            if sign == "+":
                return first + last
            elif sign == "-":
                return first - last
            elif sign == "*":
                return first * last
            else:
                return ValueError("输入的计算符号有误")

        # 定义两个栈分别存储数字和符号
        number_stack = []
        sign_stack = []
        number = 0
        for i in range(len(s)):
            # s为字符串类型,故需要根据输入的字符串,转换为相应值的数字
            if s[i] >= '0' and s[i] <='9':
                number = number * 10 + int(s[i])
                # 此处内部的值判断不可少,需要和后面的else结合,判断是否将number压入栈
                if i + 1 < len(s) and s[i + 1] >= '0' and s[i + 1] <='9': 
                    continue
                else:
                    number_stack.append(number)
                    number = 0
            # 1.判断左括号,压入符号栈
            elif s[i] == "(":
                sign_stack.append(s[i])
            
            # 2.判断右括号,计算与之匹配的左括号之间的数值运算,并将结果压入数字栈中
            elif s[i] == ")":
                while sign_stack[-1] != "(":
                    last = number_stack.pop()
                    first = number_stack.pop()
                    sign = sign_stack.pop()
                    res = computer(first, last, sign)
                    number_stack.append(res)
                # 弹出左括号
                sign_stack.pop()
            
            # 3.1 判断乘号,当符号栈为空的时候,直接压入符号栈;
            # 3.2 符号栈非空,且栈顶为*号,弹出数字栈顶两个数字,与符号栈顶符号,进行运算,结果压入数字栈中;
            # 3.3 符号栈非空,且栈顶不为*号。(此时对应一个括号内的公式,只含+-,优先级低于乘法)
            elif s[i] in ["*"]:
                if len(sign_stack) == 0:
                    sign_stack.append(s[i])
                elif sign_stack[-1] in ["*"]:
                    while len(sign_stack) != 0 and sign_stack[-1] in ["*"]:
                        last = number_stack.pop()
                        first = number_stack.pop()
                        sign = sign_stack.pop()
                        res = computer(first, last, sign)
                        number_stack.append(res)
                    sign_stack.append(s[i])
                else:
                    sign_stack.append(s[i])
            
            # 4.1 判断加减,符号栈为空,直接压入
            # 4.2 符号栈非空,栈顶为运算符,弹出数字栈顶两个数字,与符号栈顶符号,进行运算,结果压入数字栈中(即计算此前括号内公式);
            # 4.3 符号栈非空,栈顶不为运算符,直接压入栈中
            elif s[i] in ["+", "-"]:
                if len(sign_stack) == 0:
                    sign_stack.append(s[i])
                elif sign_stack[-1] in ["+", "-", "*"]:
                    while len(sign_stack) != 0 and sign_stack[-1] in ["+","-","*"]:
                        last = number_stack.pop()
                        first = number_stack.pop()
                        sign = sign_stack.pop()
                        res = computer(first, last, sign)
                        number_stack.append(res)
                    sign_stack.append(s[i])
                else:
                    sign_stack.append(s[i])
        
        # 最后计算不在括号内的部分
        while sign_stack:
            last = number_stack.pop()
            first = number_stack.pop()
            sign = sign_stack.pop()
            res = computer(first, last, sign)
            number_stack.append(res)
        # 返回值
        return number_stack[-1]