表达式求值

231 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动

表达式求值

问题描述

请写一个整数计算器,支持加减乘三种运算和括号。

示例:

输入:"(2 * (3 - 4)))* 5"

返回值:-10

分析问题

因为只支持加、减、乘、括号,所以我们根据优先级可以分为3类,即括号>乘>加、减,假设先把括号去掉,那么就剩下乘和加减运算,根据运算规则,我们需要先计算乘、再计算加、减,因此我们可以这么来考虑,我们先进行乘法运算,并将这些乘法运算后的整数值返回原表达式的相应位置,则随后整个表达式的值,就等于一系列整数加减后的值。而对于被括号分割的表达式,我们可以递归的去求解,具体算法如下。

遍历字符串s,并用变量preSign记录每个数字之前的运算符,初始化为加号。

  1. 遇到空格时跳过。
  2. 遇到数字时,继续遍历求出这个完整的数字的值,保存到num中。
  3. 遇到左括号时,需要递归的求出这个括号内的表达式的值。
  4. 遇到运算符或者表达式的末尾时,就根据上一个运算符的类型来决定计算方式。
    • 如果是加号,不需要进行计算,直接push到栈里
    • 如果是减号,就去当前数的相反数,push到栈里
    • 如果是乘号,就需要从栈内pop出一个数和当前数求乘法,再把计算结果push到栈中
  5. 最后把栈中的结果求和即可。

下面我们来看一下代码实现。

class Solution:
    def calculate(self, s):
        n = len(s)
        #存取部分数据和
        stack = []
        preSign = '+'
        num = 0
        i=0
        while i<n:
            c=s[i]
            if c==' ':
                i=i+1
                continue
            if c.isdigit():
                num = num * 10 + ord(c) - ord('0')

            #如果遇到左括号,递归求出括号内表达式的值
            if c=='(':
                j=i+1
                counts=1
                #截取出括号表达式的值
                while counts>0:
                    if s[j]=="(":
                        counts=counts+1
                    if s[j]==")":
                        counts=counts-1
                    j=j+1
                #剥去一层括号,求括号内表达式的值
                num=self.calculate(s[i+1:j-1])
                i=j-1

            if not c.isdigit() or i==n-1:
                if preSign=="+":
                    stack.append(num)
                elif preSign=="-":
                    stack.append(-1*num)
                elif preSign=="*":
                    tmp=stack.pop()
                    stack.append(tmp*num)

                num=0
                preSign=c
            i=i+1
        return sum(stack)

s=Solution()
print(s.calculate("(3+4)*(5+(2-3))"))