我的代码出了什么问题(CS50 2012 Pset 1贪婪)

时间:2013-08-01 04:45:09

标签: c cs50

我正在尝试制作一个程序,它可以提供最少量的硬币进行更改,但是如果我给出的数字不是分成四分之一的数字,它就会失败。例如,如果我输入1.25,我得到5个季度,但如果我输入1.26,我得到5个季度1镍,这当然是不正确的。我做错了什么?

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

void calculate_change(change_requested){   
        int num_quarters = 0;
        int num_dimes = 0;
        int num_nickles = 0;
        int num_pennies = 0;

        int val_quarters = 25;
        int val_dimes = 10;
        int val_nickles = 5;

        num_quarters = floor(change_requested/val_quarters);
        if(change_requested % val_quarters != 0){
            num_dimes = floor( (change_requested - (num_quarters * val_quarters))/val_dimes );
            if( change_requested - (((num_quarters * val_quarters) + (num_dimes * val_dimes))) != 0){
                num_nickles = floor( change_requested - ( (num_quarters * val_quarters) + (num_dimes * val_dimes)/val_nickles ));
                if( change_requested - (((num_quarters * val_quarters) + (num_dimes * val_dimes) + (num_nickles * val_nickles))) != 0){
                    for(int i = 0; i<change_requested - (((num_quarters * val_quarters) + (num_dimes * val_dimes) + (num_nickles * val_nickles))); i++){
                        num_pennies++;
                    }
                }
            }
        }
        if(num_quarters > 0){
            printf("%i Quarters ",num_quarters);
        }
        if(num_dimes > 0){
            printf("%i Dimes ",num_dimes);
        }
        if(num_nickles > 0){
            printf("%i Nickles",num_nickles);
        }
        if(num_pennies > 0){
            printf("%i Pennies",num_pennies);
        }
        printf("\n");

    }

int main (void){
    printf("How Much Change Do You Need?\nAmount: ");
    float change_requested = GetFloat();
    calculate_change(change_requested * 100);
    return 0;
}

3 个答案:

答案 0 :(得分:4)

我觉得你过于复杂了。如果你需要写

for(int i = 0; i<change_requested - (((num_quarters * val_quarters) + (num_dimes * val_dimes) + (num_nickles * val_nickles))); i++){

所有这一切都在一行,然后肯定是错的。您可以通过更简单的方式,通过从总金额中减去刚刚计算的硬币的价值来实现此目的,以获得其余的金额:

int vals[] = { 25, 10, 5 };
const char *names[] = { "quarters", "dimes", "nickles" };

int pennies = 100 * GetFloat(); // not good at all, btw (*)

for (int i = 0; i < 3; i++) {
    int n = pennies / vals[i];

    if (n) {
        printf("%d %s ", n, names[i]);
    }

    pennies -= n * vals[i];
}

if (pennies)
    printf("%d pennies", pennies);

printf("\n");

至于为什么GetFloat()不好:浮点数不精确,因此,例如,1.26实际上可能表示为1.25999946。当你将它转换为一个整数值时,如果你运气不好,可能会因为截断而损失一分钱。

答案 1 :(得分:1)

您的括号在您的代码中已关闭。看看这一行:

num_nickles = floor( change_requested - ( (num_quarters * val_quarters) + (num_dimes * val_dimes)/val_nickles ));

您的代码首先会评估(num_quarters * val_quarters) 125。然后它会评估出现在(num_dimes * val_dimes)的{​​{1}}。然后它将0除以(num_dimes * val_dimes)val_nickles也会0,然后将0添加到(num_quarters * val_quarters)。因此,该代码行基本上可以解决的是:
num_nickles = floor( 126 - 125 + 0)原来是1

答案 2 :(得分:0)

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

int main(void)
{
    // four kinds of coins as constant variables
    const int quarter = 25, dime = 10, nickel = 5;
    float change;
    unsigned int changeCoin, count, reminder;

    do
    {
        printf ("O hai! How much change is owned?\n");
        change = GetFloat();
    }
    while (change < 0);

    // convert input into cents
    changeCoin = round (change * 100);

    // count the coins
    count = changeCoin / quarter;
    reminder = changeCoin % quarter;

    count += reminder / dime; 
    reminder %= dime;

    count += reminder / nickel;
    reminder %= nickel;

    count += reminder;

    printf ("%d\n", count);         
}