如果 targetSum 可以通过添加数字数组中存在的数字来实现,returns 布尔值的函数

Function that returns a boolean if targetSum can be achieved by adding the numbers present in the numbers array

代码:-

def canSum(targetSum, numbers, d={}):
    if targetSum in d.keys():
        return d[targetSum]
    if targetSum == 0:
        return True
    if targetSum < 0:
        return False
    for each in numbers:
        rem = targetSum - each
        if canSum(rem, numbers, d):
            d[targetSum] = True
            return True
    d[targetSum] = False
    return False

我的问题-
当我 运行 测试用例的上述代码 - print(canSum(7, [2, 4])) 时,它 return false(这是正确的)。但是当我 运行 两个测试用例的相同代码 - print(canSum(7, [3, 5, 4])) 和 print(canSum(7, [2, 4])) 时,它 return两者都是正确的!(这是错误的)。

我不知道发生了什么。代码有问题吗?帮帮我。

问题出在 d 的可变默认参数上。

可变默认值,如 []{} 与函数关联 - 而不是该函数的特定调用。因此它将状态从一个调用传递到另一个调用。这就是为什么如果您 运行 它不止一次,您的代码就会失败。简单的说,d第二次不为空

您甚至不需要 d={}。如果你删除它,你的代码可以正常工作。

def canSum(targetSum, numbers, d):
    if targetSum in d.keys():
        return d[targetSum]
    if targetSum == 0:
        return True
    if targetSum < 0:
        return False
    for each in numbers:
        rem = targetSum - each
        if canSum(rem, numbers, d):
            d[targetSum] = True
            return True
    d[targetSum] = False
    return False

print(canSum(7, [2, 4], {}))
print(canSum(7, [3,5,4], {}))

输出:

False
True

如果您必须按原样保留 canSum 的签名,请考虑定义一个包装器,将 d={} 放入递归函数的调用中。

阅读更多:"Least Astonishment" and the Mutable Default Argument