所有整数排列对应于特定总和

时间:2013-11-20 18:21:12

标签: python recursion

我想从整数列表[3,5,7,9]生成所有排列,这会导致特定的总和值15。我实现了这个,没关系。

def add_next(seq, count, m):
    s = sum(seq)
    if s == m:
        count += 1
        print(seq)
    elif s < m:
        for i in [3,5,7,9]:
            add_next(seq + [i], count, m)
    else:
        return count

add_next([], 0, 15)

输出:

[3, 3, 3, 3, 3]
[3, 3, 9]
[3, 5, 7]
[3, 7, 5]
[3, 9, 3]
[5, 3, 7]
[5, 5, 5]
[5, 7, 3]
[7, 3, 5]
[7, 5, 3]
[9, 3, 3]

问题是如何重新编写此函数以仅返回可能的排列数作为函数结果?由于对于巨大的列表和大的和值,生成所有字符串输出是不合理的。我不完全了解如何在递归函数内外传递值。

我试过了:

def add_next2(seq, count, m):
    s = sum(seq)
    if s == m:
        count += 1
        print(seq)
    elif s < m:
        for i in [3,5,7,9]:
            count = add_next2(seq + [i], count, m)
    else:
        return count

add_next([], 0, 15)

但它返回错误TypeError: unsupported operand type(s) for +=: 'NoneType' and 'int'。因此countNone。为什么呢?

另一个选择是如何重写此函数以将其转换为生成器并一个接一个地生成输出字符串?

2 个答案:

答案 0 :(得分:1)

您的递归函数不会返回s <= m的值。对于这些情况,请从函数中返回某些内容,否则将返回None

您很可能希望在所有情况下都返回count

def add_next2(seq, count, m):
    s = sum(seq)
    if s == m:
        count += 1
    elif s < m:
        for i in [3,5,7,9]:
            count = add_next2(seq + [i], count, m)
    return count

这样可行:

>>> def add_next2(seq, count, m):
...     s = sum(seq)
...     if s == m:
...         count += 1
...     elif s < m:
...         for i in [3,5,7,9]:
...             count = add_next2(seq + [i], count, m)
...     return count
... 
>>> add_next2([], 0, 15)
11

答案 1 :(得分:1)

如果您只计算成功的递归结果,则不需要'count'作为参数。您可以将成功结果返回为1,将成功结果返回为0,让它们累积。

编辑2 更简洁但仍然可读

def add_next(seq, m):
    s = sum(seq)
    count = 1 if s == m else 0
    if s < m:
        for i in [f for f in [3,5,7,9] if s + f <= m]:
            count += add_next(seq + [i], m)
    return count

print(add_next([], 15))

编辑您还可以过滤[3,5,7,9]列表,以便for i in循环仅处理可能成功的元素。

for i in [f for f in [3,5,7,9] if s + f <= m]: