简体   繁体   中英

recursive function python, create function that generates all numbers that have same sum N

I am trying to code a recursive function that generates all the lists of numbers < N who's sum equal to N in python This is the code I wrote :

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)

this is the output I get

vvi
Out[170]: [[1, 1, 1, 1, 1, 2, 3, 4, 5, 2, 3, 4, 5, 2, 3, 4, 5, 2, 3, 4, 5]]   

I tried same thing with c++ and it worked fine

What you need to do is to just formulate it as a recursive description and implement it. You want to prepend all singleton [ j ] to each of the lists with sum Nj , unless Nj=0 in which you also would include the singleton itself. Translated into python this would be

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)

The solution contains a mechanism that will exclude permutated solutions by requiring the lists to be non-decreasing, this is done via the minelm argument that limits the values in the rest of the list. If you wan't to include permuted lists you could disable the minelm mechanism by replacing the recursion call to glist(listsum-j) .

As for your code I don't really follow what you're trying to do. I'm sorry, but your code is not very clear (and that's not a bad thing only in python, it's actually more so in C).

First of all it's a bad idea to return the result from a function via a global variable, returning result is what return is for, but in python you have also yield that is nice if you want to return multiple elements as you go. For a recursive function it's even more horrible to return via a global variable (or even use it) since you are running many nested invocations of the function, but have only one global variable.

Also calling a function fn taking arguments v and n as argument. What do that actually tell you about the function and it's argument? At most that it's a function and probably that one of the argument should be a number. Not very useful if somebody (else) is to read and understand the code.

If you want an more elaborate answer what's formally wrong with your code you should probably include a minimal, complete, verifiable example including the expected output (and perhaps observed output).

You may want to reconsider the recursive solution and consider a dynamic programming approach:

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]]

Using global variables and side effects on input parameters is generally consider bad practice and you should look to avoid.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM