Python中的子集递归求和
我很乐意得到一些帮助 我有以下问题: 我得到了一个数字列表和一个目标数字,我需要写两件事:Python中的子集递归求和,python,recursion,dynamic-programming,memoization,subset-sum,Python,Recursion,Dynamic Programming,Memoization,Subset Sum,我很乐意得到一些帮助 我有以下问题: 我得到了一个数字列表和一个目标数字,我需要写两件事: 一种递归解决方案,如果子序列的和等于目标数,则返回True,否则返回False。 例如: subset_sum([-1,1,5,4],0) # True subset_sum([-1,1,5,4],-3) # False 其次,我需要使用我在上一个解决方案中编写的内容编写一个解决方案 但是现在使用了一个字典的Memonization,其中的键是元组: (len(seq),target) 对于1号
True
,否则返回False
。
例如:
subset_sum([-1,1,5,4],0) # True
subset_sum([-1,1,5,4],-3) # False
(len(seq),target)
def subset_sum(seq, target):
if target == 0:
return True
if seq[0] == target:
return True
if len(seq) > 1:
return subset_sum(seq[1:],target-seq[0]) or subset_sum(seq[1:],target)
return False
我不确定我是否做对了,所以如果我能得到一些意见,我将不胜感激
2号:
def subset_sum_mem(seq, target, mem=None ):
if not mem:
mem = {}
key=(len(seq),target)
if key not in mem:
if target == 0 or seq[0]==target:
mem[key] = True
if len(seq)>1:
mem[key] = subset_sum_mem(seq[1:],target-seq[0],mem) or subset_sum_mem(seq[1:],target,mem)
mem[key] = False
return mem[key]
我无法得到回忆录给我正确的答案,所以我很高兴在这里得到一些指导
谢谢所有愿意帮忙的人 我修改了这个代码:
def subset_sum(seq, target):
left, right = seq[0], seq[1:]
return target in (0, left) or \
(bool(right) and (subset_sum(right, target - left) or subset_sum(right, target)))
def subset_sum_mem(seq, target, mem=None):
mem = mem or {}
key = (len(seq), target)
if key not in mem:
left, right = seq[0], seq[1:]
mem[key] = target in (0, left) or \
(bool(right) and (subset_sum_mem(right, target - left, mem) or subset_sum_mem(right, target, mem)))
return mem[key]
你能提供一些不适用的测试用例吗?这就是我编写
子集的方法
def subset_sum(seq, target):
if target == 0:
return True
for i in range(len(seq)):
if subset_sum(seq[:i] + seq[i+1:], target - seq[i]):
return True
return False
它使用了几个例子:
>>> subset_sum([-1,1,5,4], 0))
True
>>> subset_sum([-1,1,5,4], 10)
True
>>> subset_sum([-1,1,5,4], 4)
True
>>> subset_sum([-1,1,5,4], -3)
False
>>> subset_sum([-1,1,5,4], -4)
False
老实说,我不知道如何回忆它
旧的编辑:我用any()删除了解决方案
,因为在一些测试之后,我发现这会更慢
更新:出于好奇,您还可以使用:
在某些情况下,这比动态规划方法做得更好,但在另一些情况下,它会挂起(无论如何比递归方法更好)。仅供参考,这里有一个使用动态规划的解决方案:
def positive_negative_sums(seq):
P, N = 0, 0
for e in seq:
if e >= 0:
P += e
else:
N += e
return P, N
def subset_sum(seq, s=0):
P, N = positive_negative_sums(seq)
if not seq or s < N or s > P:
return False
n, m = len(seq), P - N + 1
table = [[False] * m for x in xrange(n)]
table[0][seq[0]] = True
for i in xrange(1, n):
for j in xrange(N, P+1):
table[i][j] = seq[i] == j or table[i-1][j] or table[i-1][j-seq[i]]
return table[n-1][s]
def正/负和(seq):
P、 N=0,0
对于下文中的e:
如果e>=0:
P+=e
其他:
N+=e
返回P,N
def子集_和(顺序,s=0):
P、 N=正和/负和(序号)
如果不是seq或sP:
返回错误
n、 m=len(seq),P-n+1
表=[[False]*m表示x范围内的x(n)]
表[0][seq[0]]=True
对于x范围内的i(1,n):
对于X范围内的j(N,P+1):
表[i][j]=序号[i]==j或表[i-1][j]或表[i-1][j-seq[i]]
返回表[n-1][s]
您不只是在使用的任何原因?可能是因为这是家庭作业;)如果这实际上是家庭作业,请标记为家庭作业。人们仍然会提供帮助。这是一个很好的形式,可以帮助人们了解你来自哪里。它工作得很好!非常感谢你。为了深入了解解决方案,您能解释一下回流线的作用吗?返回target in(0,left)或\(bool(right)和(subset_sum(right,target-left)或subset_sum(right,target)),如果这是家庭作业,那么您应该弄清楚它是如何工作的——以及它与原始代码的相同之处。我唯一不明白的是bool(right)对解决方案给出了什么。你能解释一下吗?嗯。在我的实验中,我得到了[]
作为某个点的返回值,因此我将向右
转换为布尔值。现在我想不出一个需要它的例子。将bool(right)
更改为right
,然后尝试:subset\u sum([2],1)
和subset\u sum\u mem([2],1)
subset\u sum=lambda seq,target:=0)或任意(subset\u sum(seq[:I]+seq[I+1:],target-v)对于I,v在枚举(seq)中,对于我们受虐狂者;
)在这种情况下,记忆化实际上是一个微不足道的字典查找。很好的解决方案!或者:`return any(subset_sum(seq[:i]+seq[i+1:],target-seq[i])for i in range(len(seq))`@user1123417:不客气,如果你发现它有用,你可以投票(作为对我们努力的奖励),如果它是解决问题最有用的,你也可以接受它(左边的绿色箭头):)非常好。备选方案:def正数\负数\和(seq):返回和(如果e>=0,则e表示和),和(如果e<0,则e表示和)
def positive_negative_sums(seq):
P, N = 0, 0
for e in seq:
if e >= 0:
P += e
else:
N += e
return P, N
def subset_sum(seq, s=0):
P, N = positive_negative_sums(seq)
if not seq or s < N or s > P:
return False
n, m = len(seq), P - N + 1
table = [[False] * m for x in xrange(n)]
table[0][seq[0]] = True
for i in xrange(1, n):
for j in xrange(N, P+1):
table[i][j] = seq[i] == j or table[i-1][j] or table[i-1][j-seq[i]]
return table[n-1][s]