繁体   English   中英

零钱的递归生成器-Python

[英]Recursive generator for change money - python

首先,感谢您的帮助。

我有此递归代码,用于从硬币列表和给定数量中计算变化的方式。

我需要编写一个递归生成器代码,以介绍每次迭代的方式。 最后的示例:

这是代码:

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]

顺便说一句,这让我想起了问题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]

在此处输入图片说明

这就是模式。 我要求完成它

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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