在我的代码中,我使用贪婪算法来使用最少的硬币数量。例如:我必须返回0.41美元,我可以使用的最小硬币数量是4:
1 - 0,25;
1 - 0.10;
1 - 0.05;
1 - 0.01;
有4种类型的硬币:0.25,0.10,0.05,0.01。
这是我的代码:
#include <stdio.h>
#include <cs50.h>
int main(void)
{
printf("Enter the sum, that you want to return you:");
float sum = GetFloat();
float quaters = 0.25;
float dime = 0.10;
float nickel = 0.05;
float penny = 0.01;
int count_q = 0,count_d = 0,count_n = 0,count_p = 0;
while(sum<0){
printf("Incorrect, enter the positive float number");
sum = GetFloat();
}
while(sum > 0){
if(sum - quaters >=0){
sum -=quaters;
count_q +=1;
}
else if((sum -quaters <0) && (sum -dime>=0)){
sum -= dime;
count_d +=1;
}
else if((sum - dime <0) &&(sum - nickel>=0) ){
sum -= nickel;
count_n +=1;
}
else if(sum - nickel <0){
sum -= penny;
count_p +=1;
}
}
printf("The number of quaters: %i\n",count_q);
printf("The number of dimes: %i\n",count_d);
printf("The number of nickels: %i\n",count_n);
printf("The number of pennies: %i\n",count_p);
}
此代码计算每种类型的硬币用于返还总和的数量。在大多数情况下,它工作正常。
但有时候,例如,当我输入数字1.12时,它会给我错误的结果:
Enter the sum, that you want to return you:1.12
The number of quaters: 4
The number of dimes: 1
The number of nickels: 0
The number of pennies: 3
我认为,问题是在最后的if语句中。但我不知道如何纠正它。
答案 0 :(得分:8)
据我所知,在最严格的意义上,代码中没有 bug ,因为实现所依据的推理(贪婪算法)是正确的。由于使用float
(单精度浮动类型)来表示您的值,因此您很可能会因重复减法而出现舍入错误。也许,如果您在代码中将float
更改为double
,则输出将与您的示例输入一样符合预期。
然而,这只会推动限制的界限。也许最好将内部代表硬币的金额表示为int
。
请注意,当第一次遇到浮点表示不准确的事实时,我认为只有当你绝对做一些火箭科学计算时才能代表某些值和舍入误差累积的不可能性,但是< em>永远与我认为是外行的计算相关。但事实并非如此。
答案 1 :(得分:1)
跟进其他人的说法,这可能会完成这项工作:用下面的代码替换现有代码中的变量声明。计算循环不需要改变,因为你明智地使用了命名数量而不是硬编码常量。
float dollars = GetFloat();
int sum = (int)(dollars*100.0 + 0.5);
int quaters = 25;
int dime = 10;
int nickel = 5;
int penny = 1;
修改:
必须在输入发生的任何地方进行上述更改。例如:
while(dollars<0){ /***/
printf("Incorrect, enter the positive float number");
dollars = GetFloat(); /***/
sum = (int)(dollars*100.0 + 0.5); /***/
}
printf("%d pennies\n", sum); /* For debugging */
我将+0.5
添加到舍入而不是截断 - 这可能会修复1.13和1.14个案例。如果没有,我会建议您查看调试器告诉您的内容。如果您在此之后仍然遇到困难,请务必使用您最新的更新代码和测试用例发布另一个问题。