【问题标题】:What's wrong with my code (CS50 2012 Pset 1 greedy)我的代码有什么问题(CS50 2012 Pset 1 贪婪)
【发布时间】:2013-08-01 04:45:08
【问题描述】:

我正在尝试制作一个提供最少硬币数量的程序来找零,但是如果我提供的数字不是分成四等份的数字,它就会惨遭失败。例如,如果我输入 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;
}

【问题讨论】:

  • change_requested 的类型是什么? float、double 还是其他?
  • 欢迎来到 Stack Overflow。请尽快阅读About 页面。请学习使用编译器警告标志,并确保打开它们并注意它们。他们在那里保护你。您绝对不应该编写诸如void calculate_change(change_requested){ ... } 之类的代码。这使用“隐式int”规则将change_requested 声明为int 类型的变量。由于范围内没有calculate_change() 的原型(函数定义不提供原型),因此参数作为double 传递。所有的地狱都应该从那里挣脱出来。 [...继续...]
  • [...continuation...] 令我惊讶的是,在 Mac OS X 上使用 gcc 进行测试时,编译器无法识别参数类型不匹配,并且进行了正确的类型转换,因此 float 表达式被转换为 int 参数,尽管范围内没有原型。我不得不求助于 count_change() 函数的单独编译来获得我从过去(苦涩)经历中所期望的行为。编译器发生变化。您仍然不应使用参数的隐式 int 声明。
  • 为了更好地衡量,最新版本的 C 语言完全放弃了“隐式 int”支持。 真的不要再这样做了。

标签: c cs50


【解决方案1】:

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

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。将其转换为整数值时,如果运气不好,可能会因截断而损失一分钱左右。

【讨论】:

    【解决方案2】:

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

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

    您的代码首先要评估(num_quarters * val_quarters),得出125。然后它评估(num_dimes * val_dimes),得出0。然后它将(num_dimes * val_dimes) 除以val_nickles,得到0,然后将0 添加到(num_quarters * val_quarters)。因此,这行代码的本质是:
    num_nickles = floor( 126 - 125 + 0) 原来是1

    【讨论】:

      【解决方案3】:
      #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);         
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-01
        相关资源
        最近更新 更多