变换金钱的递归发电器 - 蟒蛇

时间:2017-06-15 19:18:29

标签: python python-3.x

首先,感谢您的帮助。

我有这个递归代码,用于计算硬币列表和给定金额的变化方式。

我需要编写一个递归生成器代码,用于显示每次迭代的方法。最后的例子:

这是代码:

def countChange(amount, coins):
    if (amount == 0):
        return 1
    elif (amount < 0 or coins == []):
        return 0
    else:
    return (countChange(amount, coins[:-1]) + countChange(amount - coins[-1], coins))

现在,我需要用递归生成器来介绍方法。我有一部分需要编写的代码:

def change_gen(amount, coins):
    if amount == 0:
       yield ?????
    elif not (amount < 0 or coins == []):
       g = change_gen(amount, coins[:-1])
       ????? 

这应该是输出,例如:

 for e in change_gen(5,[1,2,3]):
     print(e)

 [1, 1, 1, 1, 1]
 [1, 1, 1, 2]
 [1, 2, 2]
 [1, 1, 3]
 [2, 3]

2 个答案:

答案 0 :(得分:2)

顺便说一下,这让我想起Problem 31

如果您使用 Python 3.3 + ,我们可以使用yield from撰写change_gen

def change_gen(amount, coins):
    if amount == 0:
        yield 1
    elif amount < 0 or not coins:
        yield 0
    else:
        yield from change_gen(amount, coins[:-1])
        yield from change_gen(amount - coins[-1], coins)

或没有yield from

def change_gen(amount, coins):
    if amount == 0:
        yield 1
    elif amount < 0 or not coins:
        yield 0
    else:
        for element in change_gen(amount, coins[:-1]):
            yield element
        for element in change_gen(amount - coins[-1], coins):
            yield element

测试

import random


for _ in range(10):
    amount = random.randint(0, 900)
    coins = list({random.randint(1, 100)
                  for _ in range(random.randint(1, 10))})
    assert countChange(amount, coins) == sum(change_gen(amount, coins))

工作正常,所以它似乎给出了类似的输出

注意

你应该记住,对于amount和小硬币的大值,我们可能会达到递归限制(我的机器上的最大深度接近1000。)

修改

如果你想获得使用哪些硬币,我们可以为它们添加额外的参数

def change_gen(amount, left_coins, used_coins):
    if amount == 0:
        yield used_coins
    elif amount < 0 or not left_coins:
        yield
    else:
        yield from change_gen(amount, left_coins[:-1],
                              used_coins=used_coins[:])
        yield from change_gen(amount - left_coins[-1],
                              left_coins,
                              used_coins[:] + [left_coins[-1]])

这里可能存在的问题是,在金额为负数或没有剩余硬币的情况下None对象将会产生,但没关系,我们可以使用filter从结果中过滤它们:

for e in filter(None, change_gen(5, [1, 2, 3], used_coins=[])):
    print(e)

给我们

[1, 1, 1, 1, 1]
[2, 1, 1, 1]
[2, 2, 1]
[3, 1, 1]
[3, 2]

答案 1 :(得分:0)

enter image description here

这是模式。 我要求完成它