C - 我的贪心算法不适用于CS50x

时间:2016-10-07 08:58:44

标签: c algorithm cs50

我正在做cs50x而且我的工作遇到了麻烦。我应该创建一个算法,输出最少的硬币,以回馈变化。例如0.41美元将是4个硬币,四分之一(0.25),两个硬币,(0.10)和一分(0.01)。由于某种原因,这个算法不起作用(它输出的硬币数量不正确)我无法计算出于何种原因:

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

int Coins;
float Owed;

int main(void)
{
    printf("How much is owed?\n");
    Owed = GetFloat();
    while (Owed < 0)
    {
        printf("A positive number please");
        Owed = GetFloat();
    }
    if (Owed >= 0.25)
    {
        while (Owed >=0.25)
        {
            Owed = Owed - 0.25;
            Coins++;
        }
    }

     if (Owed >= 0.1)
    {
        while (Owed >=0.1)
        {
            Owed = Owed - 0.1;
            Coins++;
        }

    }

       if (Owed >= 0.05)
    {
        while (Owed >=0.05)
        {
            Owed = Owed - 0.05;
            Coins++;
        }

    }

       if (Owed >= 0.01)
    {
        while (Owed >= 0.01)
        {
            Owed = Owed - 0.01;
            Coins++;
        }

    }
    printf("%d",Coins);
}

当我运行代码并使用0.41作为欠款时,我得到3个硬币,当答案应该是4:

GreedyNotWorkTerminalPage

2 个答案:

答案 0 :(得分:2)

当您使用float时,您需要注意在此类操作中可能会失去准确性。看看这个:Floating point inaccuracy examples

我建议您使用int来代替。

Coliru example

答案 1 :(得分:0)

您正在使用没有精确表示的数字(0.1,0.05,0.01)作为浮点数,与2/3没有精确表示形式的4位十进制数字完全相同。 C将使用最接近的浮点值,因此错误非常小,但这足以使您的比较意外失败。

想象一下,如果一个浮点数是4位小数,而你有2/3美元硬币:

  1. 以Owed = 2.0000
  2. 开头
  3. Owed&gt; = 0.6667,所以Owed- = 0.6667。现在欠了= 1.3333
  4. 1.3333&gt; = 0.6667,所以Owed- = 0.6667。现在欠了= 0.6666
  5. 糟糕! Owed = 0.6666,但不是> = 0.6667
  6. 您可以通过更改比较来解决这个问题,以避免出现一点舍入错误。不要说>=0.25>=0.1>=0.01,而是使用>=0.245>=0.095>=0.005

    但是,通常情况下,最好使用能够准确表示要使用的值的类型。而不是float美元,使用int美分。