【问题标题】:Recursive tree terminates function prematurely递归树过早终止函数
【发布时间】:2017-12-03 21:17:46
【问题描述】:

我正在尝试定义一个函数,该函数返回一个包含给定总和的所有合法硬币组合的列表。假设给定的总和是 10,而法定硬币是 5, 2, 3。在这种情况下,函数应该返回:

[[2, 2, 2, 2, 2], [3, 3, 2, 2], [5, 3, 2], [5, 5]]

我已经设法创建了一个递归函数,它可以给我正确的结果,但是通过在单独的行上打印正确的答案并混合在一堆 None 中。

如何在不提前终止函数的情况下将正确答案返回到合法解决方案列表。我知道我的功能是无效的。我自己能想到一些改进,稍后会实施。

这是我的代码:

def count_change(tot_amount, coins, used_coins=[]):

    # Sort coins and get rid of coins that are too big
    if len(used_coins) == 0:
        coins = [x for x in sorted(coins) if x <= tot_amount]

    for coin in coins:
        # If the first condition holds I want to add the printed
        # statement to a list of solution instead of printing
        if tot_amount - sum(used_coins) == coin:
            print(used_coins + [coin])
        elif tot_amount - sum(used_coins) > coin:
            print(count_change(tot_amount,
                               [x for x in coins if x <= coin],
                               used_coins + [coin]))

print(count_change(10, [5, 2, 3]))

这是输出:

[2, 2, 2, 2, 2]
None
None
None
None
None
None
None
[3, 3, 2, 2]
None
None
None
None
None
None
[5, 3, 2]
None
[5, 5]
None
None

【问题讨论】:

    标签: python recursion


    【解决方案1】:

    您只需要将那些 print 调用替换为 yield,将您的函数转换为 generator

    我还将used_coins 的默认值更改为None,因为您并不真正想要一个默认的可变参数。详情请见“Least Astonishment” and the Mutable Default Argument

    def count_change(tot_amount, coins, used_coins=None):
        # Sort coins and get rid of coins that are too big
        if used_coins is None:
            used_coins = []
            coins = [x for x in sorted(coins) if x <= tot_amount]
    
        for coin in coins:
            # If the first condition holds we have a valid combination 
            if tot_amount - sum(used_coins) == coin:
                yield used_coins + [coin]
            # Otherwise, if this coin is small enough, recurse to find combinations
            # that use this coin in addition to the existing used_coins
            elif tot_amount - sum(used_coins) > coin:
                yield from count_change(tot_amount,
                                   [x for x in coins if x <= coin],
                                   used_coins + [coin])
    
    for t in count_change(10, [5, 2, 3]):
        print(t)
    

    输出

    [2, 2, 2, 2, 2]
    [3, 3, 2, 2]
    [5, 3, 2]
    [5, 5]
    

    如果您确实需要解决方案列表,则只需将生成器运行到列表中,如下所示:

    seq = list(count_change(10, [5, 2, 3]))
    print(seq)
    

    输出

    [[2, 2, 2, 2, 2], [3, 3, 2, 2], [5, 3, 2], [5, 5]]
    

    【讨论】:

      猜你喜欢
      • 2020-09-16
      • 1970-01-01
      • 2017-03-13
      • 2012-10-24
      • 2019-12-26
      • 1970-01-01
      • 1970-01-01
      • 2012-10-29
      • 1970-01-01
      相关资源
      最近更新 更多