C 贪婪硬币计数中的整数溢出 #包括 #包括 #包括 int main(void){ printf(“输入金额:”); 浮动金额=GetFloat(); 整数=0; 而(金额!=0){ 如果(fmod(数量,0.25)==0){ 金额=金额-0.25; 硬币+=1; } 否则如果(fmod(数量,0.10)==0){ 金额=金额-0.10; 硬币+=1; } 否则如果(fmod(数量,0.05)==0){ 金额=金额-0.05; 硬币+=1; } 否则{ 金额=金额-0.01; 硬币+=1; } } printf(“硬币:%d\n”,硬币); }

C 贪婪硬币计数中的整数溢出 #包括 #包括 #包括 int main(void){ printf(“输入金额:”); 浮动金额=GetFloat(); 整数=0; 而(金额!=0){ 如果(fmod(数量,0.25)==0){ 金额=金额-0.25; 硬币+=1; } 否则如果(fmod(数量,0.10)==0){ 金额=金额-0.10; 硬币+=1; } 否则如果(fmod(数量,0.05)==0){ 金额=金额-0.05; 硬币+=1; } 否则{ 金额=金额-0.01; 硬币+=1; } } printf(“硬币:%d\n”,硬币); },c,greedy,cs50,C,Greedy,Cs50,我正在尝试实现一个小的贪婪算法,在这个算法中,用户输入一定数量的钱(例如:9.25),我们输出的硬币数量最少,我们可以兑换(25美分、10美分、5美分和1美分) 该算法适用于整数金额,如10或20,以及只需要程序使用25美分硬币的金额 如果我尝试9.10或9.01这样的数值,就会得到一个运行时错误,即有符号整数溢出。我明白这意味着什么,但我不明白硬币的价值怎么会突然这么高。你的算法不正确: 例如,使用30美分,您可以使用您的算法将其兑换为:25+5(2个硬币),即10+10+10(3个硬币)。所

我正在尝试实现一个小的贪婪算法,在这个算法中,用户输入一定数量的钱(例如:9.25),我们输出的硬币数量最少,我们可以兑换(25美分、10美分、5美分和1美分)

该算法适用于整数金额,如10或20,以及只需要程序使用25美分硬币的金额


如果我尝试9.10或9.01这样的数值,就会得到一个运行时错误,即有符号整数溢出。我明白这意味着什么,但我不明白硬币的价值怎么会突然这么高。

你的算法不正确:

例如,使用30美分,您可以使用您的算法将其兑换为:25+5(2个硬币),即10+10+10(3个硬币)。所以贪婪意味着为什么它大于25美分,然后先交换到25美分

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

int main (void) { 

    printf ("Enter amount: ");
    float amount = GetFloat();
    int coins = 0;

    while (amount != 0) {

        if (fmod(amount, 0.25) == 0) {
            amount = amount - 0.25;
            coins += 1;
        }

        else if (fmod(amount, 0.10) == 0) {
            amount = amount - 0.10;
            coins += 1;
        }

        else if (fmod(amount, 0.05) == 0) {
            amount = amount - 0.05;
            coins += 1;
        }

        else {
            amount = amount - 0.01;
            coins += 1;
        }
    }

    printf ("Coins : %d\n", coins);
}
如果你想那样做

更好的方法:

while (amount != 0) {

    if (amount >= 0.25) {
        amount = amount - 0.25;
        coins += 1;
    }

    else if (amount >= 0.10) {
        amount = amount - 0.10;
        coins += 1;
    }

    else if (amount >= 0.05) {
        amount = amount - 0.05;
        coins += 1;
    }

    else {
        amount = amount - 0.01;
        coins += 1;
    }
}
intcointypes[]={0.25,0.1,0.05,0.01};
对于(int i=0;i<4;i++){
硬币+=底价(金额/硬币类型[i];
金额-=硬币*铸币[i];
}

您的算法不正确:

例如,你可以用30美分兑换成:25+5(2个硬币),用你的算法它将是10+10+10(3个硬币)。贪婪意味着为什么它大于25美分,然后先兑换成25美分

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

int main (void) { 

    printf ("Enter amount: ");
    float amount = GetFloat();
    int coins = 0;

    while (amount != 0) {

        if (fmod(amount, 0.25) == 0) {
            amount = amount - 0.25;
            coins += 1;
        }

        else if (fmod(amount, 0.10) == 0) {
            amount = amount - 0.10;
            coins += 1;
        }

        else if (fmod(amount, 0.05) == 0) {
            amount = amount - 0.05;
            coins += 1;
        }

        else {
            amount = amount - 0.01;
            coins += 1;
        }
    }

    printf ("Coins : %d\n", coins);
}
如果你想那样做

更好的方法:

while (amount != 0) {

    if (amount >= 0.25) {
        amount = amount - 0.25;
        coins += 1;
    }

    else if (amount >= 0.10) {
        amount = amount - 0.10;
        coins += 1;
    }

    else if (amount >= 0.05) {
        amount = amount - 0.05;
        coins += 1;
    }

    else {
        amount = amount - 0.01;
        coins += 1;
    }
}
intcointypes[]={0.25,0.1,0.05,0.01};
对于(int i=0;i<4;i++){
硬币+=底价(金额/硬币类型[i];
金额-=硬币*铸币[i];
}

算法的主要问题是
fmod
函数的使用无效。根据定义,
fmod(num,denom)
的结果是

int coinTypes[] = {0.25, 0.1, 0.05, 0.01};

for (int i = 0; i < 4; i++) {
   coins += floor(amount / coinTypes[i];
   amount -= coins * coinsTypes[i];
}
其中
floor(num/denom)
为整数。 因此,
fmod(9.10,0.25)==0.1
fmod(9.10,0.10)==0.1


此外,使用浮点数的操作很少给出准确的结果。因此
amount
永远不是
0
算法的主要问题是
fmod
函数的无效使用。根据定义
fmod(num,denom)
的结果是

int coinTypes[] = {0.25, 0.1, 0.05, 0.01};

for (int i = 0; i < 4; i++) {
   coins += floor(amount / coinTypes[i];
   amount -= coins * coinsTypes[i];
}
其中
floor(num/denom)
为整数。 因此,
fmod(9.10,0.25)==0.1
fmod(9.10,0.10)==0.1


此外,使用浮点数的操作很少给出准确的结果。因此,
amount
从来都不是
0
,正如Danial Tran所说,在执行逻辑运算时最好使用int。请阅读,这样可以避免while循环

fmod = num - floor(num/denom) * denom
#包括
#包括
#包括
int main(void){
printf(“输入金额:”);
//float amount=GetFloat();//请参阅下面chqrlie的注释。
双倍金额=0.0;
scanf(“%lf”,&amount);//我不知道GetFloat()是否等同于double。所以使用scanf()。
长整型金额=(长整型)(金额*100.0);
整数=0;

如果(25如Danial Tran所说,在进行逻辑运算时最好使用int。请阅读,这样可以避免while循环

fmod = num - floor(num/denom) * denom
#包括
#包括
#包括
int main(void){
printf(“输入金额:”);
//float amount=GetFloat();//请参考下面的chqrlie注释。
双倍金额=0.0;
scanf(“%lf”,&amount);//我不知道GetFloat()是否等同于double。所以使用scanf()。
长整型金额=(长整型)(金额*100.0);
整数=0;

如果(25似乎没有人回答这个问题

如果我尝试像9.10或9.01这样的数量,我会得到一个运行时错误,有符号整数溢出,我理解它的意思,但我不明白硬币的价值怎么会突然变得这么高

因此,为了完整性,部分作为练习:

您可以使用调试器找到原因。我复制了您的代码,发现它运行了很长时间。在启动后中断一会儿,显示代码冻结,重复此检查:

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

int main (void) { 

    printf ("Enter amount: ");
    //float amount = GetFloat(); //Please refer to chqrlie's comments below.
    double amount  = 0.0;
    scanf("%lf",&amount); //I don't know GetFloat() equivalent for double. So using scanf().

    long long int amountInt = (long long int) (amount * 100.0);

    int coins = 0;

    if (25 <= amountInt) {
        coins += (amountInt/25);
        amountInt = amountInt % 25;
    }

    if (10 <= amountInt) {
        coins += (amountInt/10);
        amountInt = amountInt % 10;
    }

    if (5 <= amountInt) {
        coins += (amountInt/5);
        amountInt = amountInt % 5;
    }

    if (1 <= amountInt) {
        coins += amountInt;
    }

    printf ("Coins : %d\n", coins);
}

在中断的那一刻,
金额约为-120万,硬币约为500万。这清楚地表明,有一件事你没有检查:消极性。浮动很容易发生,你错过了准确的零,正如其他人正确推断的那样,无需重复。但如果发生这种情况,你的程序应该会运行里德:当
数量
为负数时,它就会被删除。否则,在适当的条件下,它可能会继续向负无穷大方向减去,是的,
硬币
中会出现整数溢出。似乎没有人回答这个特定的问题

如果我尝试像9.10或9.01这样的数量,我会得到一个运行时错误,有符号整数溢出,我理解它的意思,但我不明白硬币的价值怎么会突然变得这么高

因此,为了完整性,部分作为练习:

您可以使用调试器找到原因。我复制了您的代码,发现它运行了很长时间。在启动后中断一会儿,显示代码冻结,重复此检查:

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

int main (void) { 

    printf ("Enter amount: ");
    //float amount = GetFloat(); //Please refer to chqrlie's comments below.
    double amount  = 0.0;
    scanf("%lf",&amount); //I don't know GetFloat() equivalent for double. So using scanf().

    long long int amountInt = (long long int) (amount * 100.0);

    int coins = 0;

    if (25 <= amountInt) {
        coins += (amountInt/25);
        amountInt = amountInt % 25;
    }

    if (10 <= amountInt) {
        coins += (amountInt/10);
        amountInt = amountInt % 10;
    }

    if (5 <= amountInt) {
        coins += (amountInt/5);
        amountInt = amountInt % 5;
    }

    if (1 <= amountInt) {
        coins += amountInt;
    }

    printf ("Coins : %d\n", coins);
}
在中断的那一刻,
金额约为-120万,硬币约为500万。这清楚地表明,有一件事你没有检查:消极性。浮动很容易发生,你错过了准确的零,正如其他人正确推断的那样,没有必要