首页 > 解决方案 > 如何将钱(以便士)转换为单个硬币?

问题描述

我的任务是'编写一个函数 selectCoins,要求用户输入金额(以便士为单位),然后输出应用于弥补该金额的每种面额的硬币数量(从 2 英镑到 1 便士)完全正确(使用尽可能少的硬币)。例如,如果输入是 292,那么函数应该报告:1 × £2, 0 × £1, 1 × 50p, 2 × 20p, 0 × 10p, 0 × 5p, 1 × 2p, 0 × 1p。(提示:使用整数除法和余数)。

def selectCoins():
    twopound = 200
    onepound = 100
    fiftyp = 50
    twentyp = 20
    tenp = 10
    fivep = 5
    twop = 2
    onep = 1
    a = 0
    b = 0
    c = 0
    d = 0
    e = 0
    f = 0
    g = 0
    h = 0
    money = int(input('Enter how much money you have in pence'))

    while True:
        if money >= twopound:
            money = money - twopound
            a = a + 1
        elif money >= onepound:
            money = money - onepound
            b = b + 1
        elif money >= fiftyp:
            money = money - fiftyp
            c = c + 1
        elif money >= twentyp:
            money = money - twentyp
            d = d + 1
        elif money >= tenp:
            money = money - tenp
            e = e + 1
        elif money >= fivep:
            money = money - fivep
            f = f + 1
        elif money >= twop:
            money = money - twop
            g = g + 1
        elif money >= onep:
            money = money - onep
            h = h + 1
        else:
            money = 0
        break
    print(a,b,c,d,e,f,g,h)

我是编程新手,所以当我运行这段代码时,它只输入 '1 0 0 0 0 0 0 0' 当我输入 292 而不是它应该输出的内容。

标签: python

解决方案


由于您是编码新手,因此您应该开始在纸上编写您要遵循的过程,然后找出可以使用哪些工具来自动化这个过程。

重要的

按顺序阅读完整答案!
不要陷入立即阅读代码的诱惑。

我提供的解决方案是隐藏的,但您可以将鼠标悬停在它们上方或单击它们来阅读它们(如果您使用的是 StackExchange 移动应用程序,请触摸每个块中的“剧透”链接)。

算法

我要做的是:

  1. 假设我有硬币箱,每个箱都标有硬币面额。
    这些垃圾箱从最大面额到最低面额排序,我总是从最高面额的垃圾箱中挑选所需数量的硬币,然后再转到下一个垃圾箱。
  2. 在一张纸上写下我需要计算我需要的每种面额硬币数量的值。
  3. 从第一个箱子(持有最高面额的箱子)开始。
  4. 从那个垃圾箱中挑选我需要的尽可能多的硬币,这样我就不会“超过”写在纸上的数量(注意这个数字可以为零)。
    这可以通过整数除法来完成;例如,如果您的值为 700 并且 bin 的面额为 200,则您计算整数除法700 ÷ 200 = 3 (plus a remainder of 100)
  5. 计算我挑选的硬币的总数。
  6. 删除在步骤 5 中计算的值并将余数写为“新”值。
    由于您已经在步骤 4 中计算了整数除法,因此您可以计算余数。您还可以考虑在大多数编程语言中都有一个“模”运算符,它可以立即为您提供整数除法的余数。使用上面的例子,700 mod 200 = 100读作“700 模 200 是 100”,或“整数除法 700 ÷ 200 的余数是 100”。
  7. 移动到下一个硬币箱。
  8. 从第 4 步开始重复,直到我使用所有垃圾箱或值为零。

例子

假设我从值开始,292并且我有以下面额的箱子(已经从最高面额到最低面额排序):

|  200 |  100 |   50 |   20 |   10 |    5 |    2 |    1 |
+------+------+------+------+------+------+------+------+
|   I  |   II |  III |   IV |    V |   VI |  VII | VIII |

那么,让我们看看如果我应用上面的算法会发生什么:

Write the value:   292
Start with the first bin (denomination: 200)
Pick 1 coin from the bin
    The total amount picked from the bin is 200
    The remainder is 92
Strike the previous value
    The new value is 92
Move to the next bin (denomination: 100)
Pick 0 coins from the bin
    The total amount picked from the bin is 0
    The remainder is 92
Strike the previous value
    The new value is 92
Move to the next bin (denomination: 50)
Pick 1 coin from the bin
    The total amount picked from the bin is 50
    The remainder is 42
Move to the next bin (denomination: 20)
    Pick 2 coins from the bin
    The total amount picked from the bin is 20
    The remainder is 2
Move to the next bin (denomination: 10)
    Pick 0 coins from the bin
    The total amount picked from the bin is 0
    The remainder is 2
Move to the next bin (denomination: 10)
    Pick 0 coin from the bin
    The total amount picked from the bin is 0
    The remainder is 2
Move to the next bin (denomination: 5)
    Pick 0 coin from the bin
    The total amount picked from the bin is 0
    The remainder is 2
Move to the next bin (denomination: 2)
    Pick 1 coin from the bin
    The total amount picked from the bin is 2
    The remainder is 0
Done

在 Python 中实现这个

Python 是一种非常清晰的语言,它使这类任务变得容易。因此,让我们尝试将我们的算法翻译成 Python。

工具箱

假设您使用的是 Python 3.x,您需要了解一些运算符:

  • 整数除法运算符( ):如果你只用//一个斜线除,你会得到“真正的除法”(例如3 / 2 == 1.5),但是如果你使用双斜线,你会得到“整数除法(例如3 // 2 = 1
  • 模运算符( %):如上所述,此运算符返回除法的余数(例如7 % 4 == 3

一起使用,这些运算符将为您提供每一步所需的内容:

292 // 200 == 2
292 % 200 == 92

92 // 100 == 0
92 % 100 == 92

...

Python 的一个有用特性是您可以执行“多重赋值”:您可以在一个步骤中将多个值分配给多个变量:

# Initialize the value:
value = 292
# Initialize the denomination:
denomination = 200
# Calculate the amount of coins needed for the specified denomination
# and get the remainder (overwriting the value), in one single step:
coins, value = value // denomination, value % denomination
#              ^^^^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^^^^^^
#              |                      The remainder
#              The number of coins
#              (using integer division)

有了这些知识,我们就可以编写解决方案:

更正您的代码

请记住:在揭示以下解决方案之前,请阅读以上所有内容。

def selectCoins():
    twopound = 200
    onepound = 100
    fiftyp = 50
    twentyp = 20
    tenp = 10
    fivep = 5
    twop = 2
    onep = 1
    a = 0
    b = 0
    c = 0
    d = 0
    e = 0
    f = 0
    g = 0
    h = 0
    money = int(input('Enter how much money you have in pence')) # Example: 292
    # Calculate the number of coins needed and the remainder
    # The remainder will "overwrite" the value previously held in the "money" variable
    a, money = money // twopound, money % twopound # a = 1, money = 92
    b, money = money // onepound, money % onepound # b = 0, money = 92
    c, money = money // fiftyp,   money % fiftyp   # c = 1, money = 42
    d, money = money // twentyp,  money % twentyp  # d = 2, money = 2
    e, money = money // tenp,     money % tenp     # e = 0, money = 2
    f, money = money // fivep,    money % fivep    # f = 0, money = 2
    g, money = money // twop,     money % twop     # g = 1, money = 0
    e, money = money // onep,     money % onep     # e = 0, money = 0
    print(a,b,c,d,e,f,g,h)
此解决方案同时使用整数除法和余数来执行计算。

让我们以正确的方式来做:使用循环

让我们面对现实吧:上面的代码很冗长。一定有更好的方法......而且有!使用循环。考虑一下算法:你重复从一个箱子跳到下一个箱子的步骤,得到你需要的硬币数量和剩余的硬币。这可以写在一个循环中。所以,让list我们在我们的工具箱中添加一个:

denominations = [200, 100, 50, 20, 10, 5, 2, 1]
让我们将每个步骤的结果存储在第二个列表中:
coins = [] # We'll use the '.append()' method to add elements to this list
所以,从第一个“bin”开始:
n, money = money // denominations[0] , money % denominations[0]
    coins.append(n)
让我们把它放在一个循环中:
def select_coins_v2():
        denominations = [200, 100, 50, 20, 10, 5, 2, 1]
        coins = []
        money = int(input('Enter how much money you have in pence'))
        for i in range(len(denominations)):
            n, money = money // denominations[i], money % denominations[i]
            coins.append(n)
        print(coins)
就是这样!

另一个改进:只获得一次面额并使用它两次

请注意,上面的代码仍然存在问题:您阅读denominations了两次。如果面额值只能读取一次,那就太好了。当然,有一种方法:

def select_coins_v3():
        denominations = [200, 100, 50, 20, 10, 5, 2, 1]
        coins = []
        money = int(input('Enter how much money you have in pence'))
        for d in denominations:  # 'd' will hold the value of the denomination
            n, money = money // d, money % d
            coins.append(n)
        print(coins)
正如我的一个朋友所说:“快速、准确和简洁;而不是缓慢、分散和混乱”

TL;博士

  • 在 Python 3.x 中,“整数除法”运算符是//,余数(模)运算符是%.
  • 您可以在一行代码中执行多个赋值:
    a, b = 1, 2
  • 您可以将面额存储在列表中:
    denominations = [200, 100, 50, 20, 10, 5, 2, 1]
  • 您可以从面额列表中读取并在一个步骤中获得整数除法和余数:
    n, money = money // denominations[0], money % denominations[0]
  • 您可以编写一个执行上述所有操作的循环:
    for d in denominations: n, money = money // d, money % d

奖励:使用字典

如果我想同时打印面额和我使用的每种面额的硬币数量怎么办?您可以使用循环遍历这两个列表,但您也可以使用字典保持简单:

def select_coins_v4():
        denominations = [200, 100, 50, 20, 10, 5, 2, 1]
        coins = []
        money = int(input('Enter how much money you have in pence'))
        for d in denominations:  # 'd' will hold the value of the denomination
            n, money = money // d, money % d
            coins.append(n)
        number_of_coins = dict(zip(denominations, coins))
        print(number_of_coins)

Python 提供了很大的灵活性。随意尝试不同的方式来获得你需要的东西......并选择更容易的一种。

希望这可以帮助。


推荐阅读