【问题标题】:CS50 Greedy Need AdviceCS50 贪婪需要建议
【发布时间】:2017-08-17 20:19:15
【问题描述】:

我正在做cs50问题集“贪婪”。基本上是询问用户欠了多少零钱,然后输出可以等于输入金额的最小硬币数量。它工作得很好,除了当我输入 4.2 它输出 22 时它应该输出 18。

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


int main(void)
{
    float n;
    do
    {
        n = get_float("How much change is owed?\n");
    }
    while(n == EOF);

    int cents = (int)(n * 100);
    int minimumamountofcoins = 0;
    if (cents/25 >= 1){
        while (cents/25 >= 1)
        {
            cents -= 25;
            minimumamountofcoins++;
        }

    }
    if (cents/10 >= 1){
        while (cents/10 >= 1)
        {
            cents -= 10;
            minimumamountofcoins++;
        }
    }
    if(cents/5 >= 1){
        while (cents/5 >= 1)
        {
            cents -= 5;
            minimumamountofcoins++;
        }
    }
    if (cents/1 >= 1){
        while (cents/1 >= 1)
        {
            cents -= 1;
            minimumamountofcoins++;
        }
    }
    printf("The minimum amount of coins is %d\n", minimumamountofcoins);
}

【问题讨论】:

  • 尝试使用调试器逐步完成它。您也可以在 while 循环之前放弃 if 子句,它们基本上测试相同的东西。
  • 数千人中又一个“改变”问题。远离浮点,请做一些研究。
  • 使用int insted 或float 进行输入。
  • int cents = (int)(n * 100); 之后尝试打印美分。此外,所有if 条件都是多余的,您可以删除它们。

标签: c cs50


【解决方案1】:

看起来这是从 float 到 int 转换的问题。当您尝试将美元转换为美分时,您可以使用以下代码:

int cents = (int)(n * 100);

但是,这行代码,4.20 美元,返回 419 的美分值。这是舍入和浮点数的问题,因为 4.2 * 100 返回 419.99999999 而不是 420.0000000,并且整数转换截断而不是舍入。 4.18 美元也会出现这个问题,可能还有其他值。

为防止这种情况,请在强制转换前添加 0.5,如下所示:

int cents = (int)(n * 100 + 0.5);

这将确保以正确的方向进行舍入,因为您永远不会因为微不足道的浮点错误而偏离。

使用math.h 库,您还可以使用roundf() 函数,该函数适用于负数,以防万一。

int cents = (int)(roundf(n*100));

【讨论】:

  • (int)(n * 100 + 0.5) 可能会满足基本需求,但在包括负数、大数等在内的各种情况下都失败了。 C 在&lt;math.h&gt; 中有大约十几个舍入函数。使用棚子里最好的工具。
  • 很公平。由于提问者使用的是美元,我认为它们永远不会是负数,但我会编辑帖子以包含更好的舍入方法。
  • 次要:" 整数转换向下舍入" --> "整数转换截断分数" 这又与 - 数字不同。
  • 同样正确,也会修复
  • UnknowableIneffable 的一些数字琐事:考虑roundf(n*100)round(n*100.0) 之间的区别。对于接近 +/-x.xx5 的值,由于 some_float_n*some_int_100 的不精确性,第一个可能会以错误的方式舍入,其中 n*100.0 将计算为 double,而典型的额外精度提供了正确的结果。
【解决方案2】:

使用 round 函数对数字进行四舍五入。在这部分代码中,您需要添加 round 函数。

int cents = (int)(n * 100);

必须是这样的:

cents = round(n * 100);

如果您有其他此类问题,您可以使用调试器,例如 debug50,在其中通过单击行号右侧放置断点,然后在终端窗口(执行 clang 的窗口)中,您应该类型:

~/pset1/cash/ $ debug50 ./cash

或者任何你的程序被调用。这将打开调试器,在其中您将找到所有变量及其相等的值。按下播放按钮旁边的按钮可以向前移动一行代码。

【讨论】:

    猜你喜欢
    • 2017-07-04
    • 1970-01-01
    • 2011-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多