Изучение C, нужна помощь с решением Greedy CS50

Я очень новичок в C. Я работаю с Python. Я хотел бы знать, где я ошибся с моим кодом.

Я решаю жадную задачу cs50. Что не так с моим кодом? С некоторыми номерами работает, с другими нет. Я пытаюсь получить ответ от пользователя, спрашивающего, сколько сдачи вернуть, а затем рассчитать минимальное количество монет, которые я могу вернуть, используя только 0,25 доллара, 0,10 доллара, 0,05 доллара, 0,01 доллара.

#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 minimumamountofcoins = 0;
    if (n/.25 >=1){
        do 
        {
            n -= .25;
            minimumamountofcoins++;
        }
        while (n/.25 >= 1);
    }
    if (n/.1 >=1){
        do
        {
            n -= .1;
            minimumamountofcoins++;
        }
        while (n/.1 >=1);
    }
    if(n/.05 >=1){
        do
        {
            n -= .05;
            minimumamountofcoins++;
        }
        while (n/.05 >=1);
    }
    if (n/.01 >=1){
        do
        {
            n -= .01;
            minimumamountofcoins++;
        }
        while (n/.01 >=1);
    }
    printf("The minimum amount of coins is %d\n", minimumamountofcoins);
}

Новый код: (работает отлично кроме входа в 4.2)

#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);
}

person R_C    schedule 16.08.2017    source источник
comment
Почему бы не привести пример ввода, для которого ваш код не работает? Для этого ввода скажите, какой вывод вы ожидаете и что вместо этого возвращает ваша программа.   -  person John Coleman    schedule 16.08.2017
comment
Пожалуйста, изучите вопросы об изменении. Совет состоит в том, чтобы работать с целыми числами и центами. Математика с плавающей запятой нарушена?   -  person Weather Vane    schedule 16.08.2017
comment
Несколько советов: используйте целые числа (со всеми денежными суммами в пенни), вам не нужен последний цикл while .01 (оставшаяся сумма является количеством пенни); заменить количество слов на количество,   -  person jarmod    schedule 16.08.2017
comment
Что такое cs50.h? Содержит ли он определение функции get/_float(...)?   -  person MCG    schedule 16.08.2017
comment
Подобный код Вывод значений float и int для простого вычисления недавно рассматривался.   -  person chux - Reinstate Monica    schedule 16.08.2017
comment
@MCG посмотрите информацию о теге для cs50. Он содержит библиотеку, которая обрабатывает некоторые основные задачи ввода-вывода, и теоретически позволяет студентам сосредоточиться на том, что более важно. Лично я считаю это плохой идеей в том смысле, что в C такие детали являются одной из важных вещей, которые студент должен изучить.   -  person John Coleman    schedule 16.08.2017
comment
Вместо while (n/.1 >=1); используйте while (n >= (0.01 - 0.005));...   -  person chux - Reinstate Monica    schedule 16.08.2017


Ответы (1)


Поскольку вы не включили тестовые случаи, я сделал свой собственный. Вот некоторые из случаев, для которых ваш алгоритм не возвращает правильный ответ:

.04, .11, .17, .19, .21, .26, .32 и т.д.

Все эти случаи терпят неудачу при подсчете количества пенни (в последнем цикле do-while), и все они возвращают на одну монету меньше, чем должны. Это из-за ошибки с числами с плавающей запятой. С операторами печати я обнаружил, что при вычислении деления на последний пенни каждый раз происходило одно и то же:

n/.01 = 0.99999999

Это явно не предназначено, так как это должно быть равно 1, а последняя копейка должна быть добавлена ​​к общей сумме. Таким образом, ваш код, который теоретически работает, не работает из-за чисел с плавающей запятой.

Чтобы избежать этого, вы можете сделать что угодно, например, отслеживать доллары и центы отдельно как целые числа, изменить условие на n/.01 >= .9999 вместо n/.01 >= 1, рассматривать сумму денег, для которой вы выполняете вычисления, как целое число центов или любое другое количество вещей.

Лично я предпочитаю последний вариант, рассматривая сумму денег как целое число центов. Это легко сделать, так как все, что вам нужно сделать, чтобы преобразовать доллары в центы, умножить на 100. Таким образом, проще всего использовать тот же алгоритм, за исключением использования целых чисел.

Таким образом, код будет выглядеть примерно так:

int main(){
    float n;
    //code that parses in the amount of money, n now stores that amount
    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);
}
person Lavaman65    schedule 16.08.2017
comment
Рад, что смог помочь! - person Lavaman65; 17.08.2017
comment
Еще кое-что. Кажется, он не принимает 4.2. Должно быть 18, но возвращает 22. - person R_C; 17.08.2017
comment
Что вы имеете в виду под 4.2? ой. - person Lavaman65; 17.08.2017
comment
Когда я запускаю его на своей машине, он возвращает 18. Это должно быть какая-то другая ошибка с вашей стороны. - person Lavaman65; 17.08.2017
comment
Нет, пожалуйста, задайте новый вопрос, если у вас другая проблема - person Lavaman65; 17.08.2017