我正在尝试编写一个生成所有数字列表的递归函数< N在python中的总和等于N. 这是我写的代码:
def fn(v,n):
N=5
global vvi
v.append(n) ;
if(len(v)>N):
return
if(sum(v)>=5):
if(sum(v)==5): vvi.append(v)
else:
for i in range(n,N+1):
fn(v,i)
这是我得到的输出
vvi
Out[170]: [[1, 1, 1, 1, 1, 2, 3, 4, 5, 2, 3, 4, 5, 2, 3, 4, 5, 2, 3, 4, 5]]
我用c ++尝试了同样的事情,它运行良好
答案 0 :(得分:2)
您需要做的是将其表述为递归描述并实现它。您希望将所有单身[j
]添加到总和为N-j
的每个列表中,除非您N-j=0
中还包含单身本身。转换为python这将是
def glist(listsum, minelm=1):
for j in range(minelm, listsum+1):
if listsum-j > 0:
for l in glist(listsum-j, minelm=j):
yield [j]+l
else:
yield [j]
for l in glist(5):
print(l)
该解决方案包含一种机制,通过要求列表不减少来排除置换解决方案,这是通过限制列表其余部分中的值的minelm
参数来完成的。如果您不想包含置换列表,可以通过将递归调用替换为minelm
来禁用glist(listsum-j)
机制。
至于你的代码,我并没有真正遵循你想要做的事情。对不起,但你的代码不是很清楚(只有在python中这不是一件坏事,在C语言中实际上更是如此)。
首先,通过全局变量从函数返回结果是一个坏主意,返回结果是return
的用途,但是在python中你还有yield
,如果你很好想要随时返回多个元素。对于递归函数,通过全局变量(甚至使用它)返回更加可怕,因为您运行了许多函数的嵌套调用,但只有一个全局变量。
还调用函数fn
,将参数v
和n
作为参数。这实际上告诉你关于函数及其论证的内容是什么?至多它是一个函数,可能其中一个参数应该是一个数字。如果有人(其他人)要阅读并理解代码,那就没有用了。
如果你想要更详细的回答你的代码的正式错误,你应该包括一个minimal, complete, verifiable example,包括预期的输出(以及可能观察到的输出)。
答案 1 :(得分:1)
您可能想重新考虑递归解决方案并考虑动态编程方法:
def fn(N):
ways = {0:[[]]}
for n in range(1, N+1):
for i, x in enumerate(range(n, N+1)):
for v in ways[i]:
ways.setdefault(x, []).append(v+[n])
return ways[N]
>>> fn(5)
[[1, 1, 1, 1, 1], [1, 1, 1, 2], [1, 2, 2], [1, 1, 3], [2, 3], [1, 4], [5]]
>>> fn(3)
[[1, 1, 1], [1, 2], [3]]
对输入参数使用global
变量和副作用通常被认为是不好的做法,你应该避免使用。