贪婪算法中的 for 循环没有中断,而是无限地请求输入

For loop in a greedy algorithm isn't breaking, is asking for input infinitely

我正在创建一个贪婪循环,它找到用于返回 CS50 的 pset1 值的最小数量的硬币,但我无法解释为什么我的 while 循环是 运行 无限。

我已经修改过了,无法让它逃脱。

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

// declare variable change_owed, num_coins, and input globally
float change_owed;
float input;
int num_coins;

int main(void)
{
    // makes sure the input is non-negative
    do
    {
        input = get_float("Amount paid\n");
    }
    while(change_owed <=0);
    input = round(input);

    // begin checking 
    while(input > 0)
    {
        if(input - .25 > 0) // quarters
        {
            num_coins++; // number of coins used, to be printed later, is incremented
            input = input - .25; // coin is subtracted from total
        }
        else if (input - .10 > 0) // dimes
        {
            num_coins++;
            input = input - .10;
        }   
        else if (input - .05 > 0) // nickels
        {
            num_coins++;
            input = input - .05;
        } 
        else if (input - .01 > 0) // pennies
        {
            num_coins++;
            input = input - .01;
        } 
    }
    printf("%i", num_coins);
}

您的第一个 do/while 循环的条件是 change_owed <= 0,但循环体内没有任何内容可以更改该值。由于它是一个初始化为 0 的全局变量,并且在循环进入之前不会更改,因此在检查 while 条件时它的值将始终为 0。这会导致循环永远不会终止。

问题

while(change_owed <=0); 是一个无限循环,因为 change_owed 总是 0。当然应该是 while(input <=0);


input = round(input); 没什么意义。 round() 不四舍五入到最接近的 0.01,而是四舍五入到最接近的整数。

代码的结果结果永远是quarters.


第二个循环也是一个潜在的无限循环。

考虑当 input > 0input - .01 > 0 为 false 时会发生什么 --> 无限循环。一旦 input = round(input); 修复,这通常会出现。

while(input > 0)
{
    if(input - .25 > 0) // quarters
    { ... }
    else if (input - .10 > 0) // dimes
    { ... }
    else if (input - .05 > 0) // nickels
    { ... }
    else if (input - .01 > 0) // pennies
    { ... }
}

顺便说一句,

当然 if(input - .25 > 0) 应该是 if(input - .25 >= 0)(或更好的 if(input >= 0.25f)。使用 >= 而不是 >


大图。使用整数。

int main(void) {
  //float change_owed;
  float input;
  long long num_coins = 0;
  do {
    input = get_float("Amount paid\n");
  } while (input <= 0);
  long long input_cents = llround(input * 100.0);

  // begin checking
  while (input_cents > 0) {
    if (input_cents >= 25) {
      num_coins++;
      input_cents -= 25;
    } else if (input_cents >= 10) {
      num_coins++;
      input_cents -= 10;
    } else if (input >= 5) {
      num_coins++;
      input_cents -= 5;
    } else if (input >= 1) {
      num_coins++;
      input_cents -= 1;
    }
  }
  printf("%lld\n", num_coins);
}

可能的额外效率而不是简单地 num_coins++;

  if (input_cents > 0) {
    num_coins += input_cents/25;
    input_cents %= 25;
    num_coins += input_cents/10;
    input_cents %= 10;
    num_coins += input_cents/5;
    input_cents %= 5;
    num_coins += input_cents;
  }