我有以下算法递归地解决子集求和问题:
def findSubset(alist, targ, i, sumsofar):
if sumsofar == targ:
return True
if i == len(alist):
return False
inc = findSubset(alist, targ, i+1, sumsofar+alist[i])
noninc = findSubset(alist, targ, i+1, sumsofar)
return inc or noninc
该算法工作正常,但它只给出一个布尔答案。所以,如果我这样称呼它:
alist = [4, 6, 21, 29, 37, 50]
findSubset(alist, 76, 0, 0)
>>> True
但我希望它返回[4, 6, 29, 37]
这是我改变算法的尝试:
def findSubset(alist, targ, i, sumsofar, new):
if sumsofar == targ:
return new
if i == len(alist):
return []
inc = findSubset(alist, targ, i+1, sumsofar+alist[i], new.append(alist[i]))
noninc = findSubset(alist, targ, i+1, sumsofar, new)
return inc or noninc
使用它的地方:
alist = [4, 6, 21, 29, 37, 50]
findSubset(alist, 76, 0, 0, [])
>>>AttributeError: 'NoneType' object has no attribute 'append'
我必须做些什么来使其发挥作用,甚至可能?
答案 0 :(得分:1)
我的以下代码有效:
def findSubset(alist, targ, i, sumsofar, listsofar):
if sumsofar == targ:
return True, listsofar
if i == len(alist):
return False, listsofar
inc, inclistsofar = findSubset(alist, targ, i+1, sumsofar+alist[i], listsofar + [alist[i]])
noninc, noninclistsofar = findSubset(alist, targ, i+1, sumsofar, listsofar)
if inc:
return inc, inclistsofar
else:
return noninc, noninclistsofar
alist = [4, 6, 21, 29, 37, 50]
print findSubset(alist, 76, 0, 0, [])
list.append()是一个就地操作。它返回None类型,但您需要将列表作为参数传递。
答案 1 :(得分:0)
李恒峰解决方案的改进。使用默认参数可以在没有零和空列表的情况下进行更好的调用find_subset(alist, 76)
:
def find_subset(alist, targ, i=0, sumsofar=0, listsofar=None):
if listsofar is None:
listsofar = []
if sumsofar == targ:
return True, listsofar
if i == len(alist):
return False, listsofar
inc, inclistsofar = find_subset(alist, targ, i+1, sumsofar + alist[i], listsofar + [alist[i]])
noninc, noninclistsofar = find_subset(alist, targ, i+1, sumsofar, listsofar)
if inc:
return inc, inclistsofar
else:
return noninc, noninclistsofar
alist = [4, 6, 21, 29, 37, 50]
print(find_subset(alist, 76))
<强>更新强>
根据Blckknght的评论进一步改进:
def find_subset(alist, targ, i=0, sumsofar=0, listsofar=None):
if listsofar is None:
listsofar = []
if sumsofar == targ:
return listsofar
if i == len(alist):
return None
inclistsofar = find_subset(alist, targ, i+1, sumsofar + alist[i],
listsofar + [alist[i]])
if inclistsofar:
return inclistsofar
else:
noninclistsofar = find_subset(alist, targ, i+1, sumsofar, listsofar)
return noninclistsofar
alist = [4, 6, 21, 29, 37, 50]
print(find_subset(alist, 76))
print(find_subset(alist, 100))
print(find_subset(alist, 1000))
print(find_subset(alist, 4))
print(find_subset(alist, 17))
输出:
[4, 6, 29, 37]
[21, 29, 50]
None
[4]
None