递归函数python,创建生成具有相同和N的所有数字的函数

时间:2017-04-12 06:10:09

标签: python recursion

我正在尝试编写一个生成所有数字列表的递归函数< 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 ++尝试了同样的事情,它运行良好

2 个答案:

答案 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,将参数vn作为参数。这实际上告诉你关于函数及其论证的内容是什么?至多它是一个函数,可能其中一个参数应该是一个数字。如果有人(其他人)要阅读并理解代码,那就没有用了。

如果你想要更详细的回答你的代码的正式错误,你应该包括一个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变量和副作用通常被认为是不好的做法,你应该避免使用。