【问题标题】:Learning C, need some assistance with "Greedy" CS50 solution学习 C,需要一些“贪婪”CS50 解决方案的帮助
【发布时间】:2017-08-16 00:15:39
【问题描述】:

我对 C 很陌生。我来自 python 背景。我想知道我的代码哪里出错了。

我正在做 cs50 贪心问题。我的代码有什么问题?它适用于某些数字,但其他数字不起作用。我试图从用户那里得到一个输入,询问要返还多少零钱,然后计算我可以仅使用 $.25、$.10、$.05、$.01 返还的最小硬币数量

#include <cs50.h>
#include <stdio.h>


int main(void)
{
    float n;
    do
    {
        n = get_float("How much change is owed?\n");
    }
    while(n == EOF); 
    int minimumamountofcoins = 0;
    if (n/.25 >=1){
        do 
        {
            n -= .25;
            minimumamountofcoins++;
        }
        while (n/.25 >= 1);
    }
    if (n/.1 >=1){
        do
        {
            n -= .1;
            minimumamountofcoins++;
        }
        while (n/.1 >=1);
    }
    if(n/.05 >=1){
        do
        {
            n -= .05;
            minimumamountofcoins++;
        }
        while (n/.05 >=1);
    }
    if (n/.01 >=1){
        do
        {
            n -= .01;
            minimumamountofcoins++;
        }
        while (n/.01 >=1);
    }
    printf("The minimum amount of coins is %d\n", minimumamountofcoins);
}

新代码:(除了进入 4.2 时可以正常工作)

#include <cs50.h>
#include <stdio.h>


int main(void)
{
    float n;
    do
    {
        n = get_float("How much change is owed?\n");
    }
    while(n == EOF);

    int cents = (int)(n * 100);
    int minimumamountofcoins = 0;
    if (cents/25 >= 1){
        while (cents/25 >= 1)
        {
            cents -= 25;
            minimumamountofcoins++;
        }

    }
    if (cents/10 >= 1){
        while (cents/10 >= 1)
        {
            cents -= 10;
            minimumamountofcoins++;
        }
    }
    if(cents/5 >= 1){
        while (cents/5 >= 1)
        {
            cents -= 5;
            minimumamountofcoins++;
        }
    }
    if (cents/1 >= 1){
        while (cents/1 >= 1)
        {
            cents -= 1;
            minimumamountofcoins++;
        }
    }
    printf("The minimum amount of coins is %d\n", minimumamountofcoins);
}

【问题讨论】:

  • 为什么不举一个您的代码不起作用的输入示例?对于该输入,请说出您期望的输出以及程序返回的内容。
  • 请研究“改变”问题。建议使用整数和美分。 Is floating point math broken?
  • 一些建议:使用整数(所有货币金额以便士为单位),您不需要最后的 .01 while 循环(剩余金额便士数);将“数量”一词全部替换为“计数”,
  • 什么是 cs50.h ?是否包含 get/_float(...) 函数的定义?
  • @MCG 查看cs50 的标签信息。它包含一个处理某些基本 IO 任务的库,其理论是它允许学生专注于更重要的事情。就个人而言,我认为这是一个坏主意,因为在 C 语言中这些细节是学生需要学习的重要内容之一。

标签: c cs50


【解决方案1】:

由于您没有包含测试用例,所以我自己做了。以下是您的算法未返回正确答案的一些情况:

.04、.11、.17、.19、.21、.26、.32 等

这些情况在计算便士的数量时都失败了(在最后的 do-while 循环中),并且它们都返回了比它们应该少的一枚硬币。这是因为浮点数的错误。使用打印语句,我发现在计算最后一分钱的除法时,每次都会发生同样的事情:

n/.01 = 0.99999999

这显然不是故意的,因为这应该等于 1,最后一分钱应该加到总数中。因此,理论上有效的代码由于浮点数而被破坏。

为避免这种情况,您可以做很多事情,例如将美元和美分分别记录为整数,将条件更改为 n/.01 &gt;= .9999 而不是 n/.01 &gt;= 1,处理您正在做的金额计算为整数美分或任何其他数量的东西。

就个人而言,我更喜欢最后一种选择,将金额视为整数美分。这很容易做到,因为将美元转换为美分只需乘以 100。因此,最简单的方法是使用相同的算法,但使用整数除外。

因此,代码如下所示:

int main(){
    float n;
    //code that parses in the amount of money, n now stores that amount
    int cents = (int)(n * 100);
    int minimumamountofcoins = 0;
    if (cents/25 >= 1){
        while (cents/25 >= 1)
        {
            cents -= 25;
            minimumamountofcoins++;
        }

    }
    if (cents/10 >= 1){
        while (cents/10 >= 1)
        {
            cents -= 10;
            minimumamountofcoins++;
        }
    }
    if(cents/5 >= 1){
        while (cents/5 >= 1)
        {
            cents -= 5;
            minimumamountofcoins++;
        }
    }
    if (cents/1 >= 1){
        while (cents/1 >= 1)
        {
            cents -= 1;
            minimumamountofcoins++;
        }
    }
    printf("The minimum amount of coins is %d\n", minimumamountofcoins);
}

【讨论】:

  • 很高兴能帮上忙!
  • 还有一件事。它似乎不接受 4.2 它应该是 18 但它返回 22
  • 4.2 是什么意思?哦。
  • 当我在我的机器上运行它时,它返回 18。它一定是你的其他错误
  • 不,如果您有其他问题,请提出一个新问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多