讨论/技术交流/求大佬帮忙看下问题:实现一个计算器/
求大佬帮忙看下问题:实现一个计算器

题目:实现一个计算器

首先把输入的字符串转为列表,读取的时候不断从列表左端pop元素
helper用于存储算式中的数字(其实就是栈)
sign用于保存当前数字的符号,初始化为+
num用于保存当前数字
遇到运算符号或者列表空了说明读完了一个数字,于是根据sign的不同选择nums的正负号,存入栈中,然后更新sign并清零nums记录下一对儿符合和数字的组合;如果遇到 ( 开始递归处理括号内的表达式,遇到 ) 结束递归
代码如下:

class Solution:
    def calculate(self, s: str) -> int:
        s = list(s)
        print(s)
        helper = []
        sign = '+'
        num = 0

        while s:
            tmp = s.pop(0)
            if '0' <= tmp <= '9':
                num = num * 10 + int(tmp)
            if tmp == '(':
                num = self.calculate(s)
                print(s)
            if not tmp.isdigit() and tmp != ' ' or not len(s):
                if sign == '+':
                    helper.append(num)
                elif sign == '-':
                    helper.append(-num)
                print('helper:', helper)
                num = 0
                sign = tmp
            if tmp == ')':
                break

        res = 0
        for i in helper:
            res += i
        print(res, s)
        return res

但是s="1+(4+5+2)-3"时输出是错的,然后相关信息打印如下:
9D4102D9-D34E-4db6-9A46-0A090CB9D5DD.png
其中划红线的地方就是错误的地方,可以看到在递归结束之后'4', '+', '5', '+', '2', ')'这些已经pop掉的元素依然存在,但是列表是可变类型数据啊?传递的不是引用吗,比如下面是我仿照这个代码的逻辑写的一个简化版的代码:

def func(a):
    a.pop()
    if len(a) > 2:
        func(a)
    print(a)


func([1, 2, 3, 4, 5, 6, 7])

输出结果:
4EB8344B-8641-4ddc-ACBE-EE8584FFBB9E.png
可以看到递归中的操作也对最外层的列表产生了影响,所以按理来说最上面那个代码在红线那里的输出应该是['-', '3']才对吧。。不知道有没有大佬可以解释一下QAQ

共 2 个回复
def calculate(self, s: str) -> int:        
    s = list(s)
    ...
    while s:
        tmp = s.pop(0)

你 pop 的是每次调用函数时候生成的 list
并没有修改 str 也不会作用到外面

类似下面

def func(a):
    
    a = list(a)
    
    a.pop()
    if len(a) > 2:
        func(a)
    print(a)


func([1, 2, 3, 4, 5, 6, 7])

简单的改造思路:

class Solution:
    def recurse(self, s: list) -> int:
        print(s)
        ...
        while s:
            tmp = s.pop(0)
            ...
            num = self.recurse(s)
        ...
        return res
    def calculate(self, s: str) -> int:        
        return self.recurse(list(s))
1

啊懂了 感谢大佬!!!