CS50 greedy.c代码问题求助:check50测试未通过排查
嘿,我来帮你排查这段CS50 greedy.c代码的问题哈~先看check50给出的两个失败用例:输入0.15没输出预期的2,输入4.2直接超时退出,这俩问题其实都是同一个根源导致的。
问题核心:浮点数精度误差
你现在用float类型来存储转换后的分(cents),但很多十进制小数没法被二进制浮点数精确表示,这就触发了逻辑bug:
- 当输入0.15时,
0.15 * 100得到的不是精确的15,而是14.999999...。这个值不满足>=25、>=10、>=5的条件,直接进入最后一个减1分的循环,会执行14次,输出14而非预期的2。 - 输入4.2时,
4.2 *100得到的是419.999969...而非420。处理完大面额后剩下9.999969...,进入减1分的循环时,浮点数的精度问题会让cents永远处于略大于0的状态,循环无法终止,直接导致超时。
修复方案
解决思路很简单:把分的数值转换成整数类型,彻底避开浮点数精度问题。具体可以这么改:
- 引入
math.h头文件,用round()函数把转换后的浮点数四舍五入成精确整数; - 把
cents的类型从float改成int。
修改后的代码示例:
#include <cs50.h> #include <stdio.h> #include <math.h> // 引入math.h以使用round函数 int main(void) { float change; do { printf("O hai! How much change is owed?\n"); change = get_float(); } while (change < 0 ); // 用round函数将浮点数转换为精确的整数分,避免精度误差 int cents = round(change * 100); int counter = 0; // 外层while循环其实多余,内层四个循环已经能把cents减到0 while (cents >= 25) { cents -= 25; counter++; } while (cents >= 10) { cents -= 10; counter++; } while (cents >= 5 ) { cents -= 5; counter++; } while (cents >= 1 ) { cents -= 1; counter++; } printf("%i\n", counter); }
另外提一句,你原来的外层while (cents > 0)是多余的,因为内层四个循环已经会把cents减到0,去掉后代码更简洁。
这样修改后,再跑check50应该就能全通过啦~
内容的提问来源于stack exchange,提问作者jstrnbrg
相关产品推荐
相关产品推荐

