Python 递归程序,以获得所有子集与给定的总和包括重复
我正在尝试编写一个以以下内容作为输入的程序:Python 递归程序,以获得所有子集与给定的总和包括重复,python,recursion,Python,Recursion,我正在尝试编写一个以以下内容作为输入的程序: 允许的号码列表(arr) 总计(总和) 它应该返回arr中所有可能的数字组合,这些数字加起来等于sum 这就是我到目前为止所做的: def printAllSubsetsRec(arr, v, sum): if sum == 0: return [v] if len(arr) == 0: return v1 = [] + v v1.append(arr[0]) without
arr
)总和
)arr
中所有可能的数字组合,这些数字加起来等于sum
这就是我到目前为止所做的:
def printAllSubsetsRec(arr, v, sum):
if sum == 0:
return [v]
if len(arr) == 0:
return
v1 = [] + v
v1.append(arr[0])
without_first = printAllSubsetsRec(arr[1:], v, sum)
with_first = printAllSubsetsRec(arr[1:], v1, sum - arr[0])
if with_first and without_first:
return with_first + without_first
elif with_first:
return with_first
elif without_first:
return without_first
def array_sums(arr, sum):
v = []
return printAllSubsetsRec(arr, v, sum)
问题是它不会返回所有的子集,包括重复
例如:
print(array_sums([1,3,5],5))
# [[1, 1, 1, 1, 1], [1, 1, 3], [1, 3, 1], [3, 1, 1], [5]]
我该怎么做呢?每次递归时,我都会为
arr
中的每个数字创建一个新的分支。我保留了总和与目标匹配的分支,并停止探索总和超过目标的分支
更快(沿调用链向下传递分支的累计总和)
def数组_和(arr:Set[int],target:int)->List[List[int]:
最小值=最小值(arr)
def go(
正在进行中:List[Tuple[List[int],int]],
完成:列表[列表[int]]
)->List[List[int]]:
现在正在进行中,新完成=[],[]
对于分支机构,汇总进行中:
对于arr中的i:
#任何低于“目标值”小于“最小值”的值都会超出目标值
如果总和+列表[列表[int]]:
def go(acc:List[List[int]])->List[List[int]]:
进行中=[
分支机构+[i]
行政协调会分部
因为我在arr
如果总和(分支)<目标
]
完成=[acc中分支的分支如果总和(分支)=目标]
如果未进行,则返回完成,否则继续(进行中+完成)
返回go([[]))
您可以对生成器使用递归:
def subsets(arr, _sum, c = []):
if sum(c) == _sum:
yield c
else:
for i in arr:
if sum(c+[i]) <= _sum:
yield from subsets(arr, _sum, c+[i])
print(list(subsets([1,3,5], 5)))
这个问题是一种划分问题。尽管它是
NP难
,但您可以使用动态编程
在pseuso多项式时间
内求解。如果列表中的数字重复,是否要复制输出。e、 g.[1,3,5,5],5
是否包含两份[5]
?或者换句话说,我们可以假设arr
是一个集合吗?@JoelBerkeley是的,我们可以假设arr
是一个集合。
def array_sums(arr: Set[int], target: int) -> List[List[int]]:
def go(acc: List[List[int]]) -> List[List[int]]:
in_progress = [
branch + [i]
for branch in acc
for i in arr
if sum(branch) < target
]
complete = [branch for branch in acc if sum(branch) == target]
return complete if not in_progress else go(in_progress + complete)
return go([[]])
def subsets(arr, _sum, c = []):
if sum(c) == _sum:
yield c
else:
for i in arr:
if sum(c+[i]) <= _sum:
yield from subsets(arr, _sum, c+[i])
print(list(subsets([1,3,5], 5)))
[[1, 1, 1, 1, 1], [1, 1, 3], [1, 3, 1], [3, 1, 1], [5]]