Оптимизировать несколько операторов if else в C

#c #if-statement #optimization #simplification

#c #if-statement #оптимизация #упрощение

Вопрос:

Код:

 #include <stdio.h>
    int main(void)
    {
        int coins = 0;
        float cash_owed = 0;
        printf("Cash owed: ");
        scanf("%f" , amp;cash_owed);
        while(cash_owed > 0)
        {
            if(cash_owed >= 0.25)
            {
                cash_owed -= 0.25;
                coins  ;
            }
            else if(cash_owed >= 0.10)
            {
                cash_owed -= 0.10;
                coins  ;
            }
            else if(cash_owed >= 0.05)
            {
                cash_owed -= 0.05;
                coins  ;
            }
            else if(cash_owed >= 0.01) 
            {
                cash_owed -= 0.01;
                coins  ;
            }
        }
        printf("%in", coins);
        return 0;
    }
  

Таким образом, в основном это жадный алгоритм. Он принимает причитающиеся денежные средства в качестве входных данных, оценивает минимальное количество монет для выдачи. (Валюта США). Я думаю, что в моем коде так много повторений. Он не оптимизирован. Может ли кто-нибудь помочь мне здесь?

Комментарии:

1. Какую оптимизацию вы ищете? Время выполнения? Кодировать? Размер исполняемого файла? Размер образа программы? Если это codesize, вы можете уменьшить его, удалив отступ.

2. Если вы не указываете, для чего вы оптимизируете, обычно предполагается «скорость», а «не оптимизированный» означает «работает недостаточно быстро», что не связано с повторением кода. Вы хотите только удалить повторение или также ускорить его?

3. Существует аналитическое решение вашей проблемы с использованием modulo . Нет необходимости в цикле while. Вы можете хранить значения монет в массиве и переходить от самых больших к самым маленьким монетам.

4. Хранение денежной суммы в переменной с плавающей запятой опасно. Вы рискуете получить $ 0.2999994 (или что-то еще) из-за проблем с точностью. Сохраните число в an int , измеренное в центах.

5. @Quimby Не могли бы вы уточнить? Я ищу именно этот метод

Ответ №1:

Во-первых, вы никогда не должны (если у вас нет веской причины, и «в одном долларе 100 центов» не является веской причиной) использовать числа с плавающей запятой для валюты. Они могут генерировать ошибки округления. Вместо этого используйте целые числа, а выходные данные форматируйте позже.

И, используя это, я бы сделал что-то вроде этого:

 int coins = 0;
int cash_owed = 0;
printf("Cash owed (in cents): ");
scanf("%d" , amp;cash_owed);

int coin_type[] = {25, 10, 5, 1};

for(int i=0; i<sizeof(coin_type)/sizeof(coin_type[0]); i  ) {
    while(cash_owed >= coin_type[i]) {
        cash_owed -= coin_type[i];
        coins  ;
    }
}
  

Вот пример того, как печатать валюту:

 int cents = 7334;
printf("$%d.%d", cents/100, cents%100);
  

Комментарии:

1. Никогда. Бывают случаи, когда значение с плавающей запятой подходит для денег. Возможно, зарезервировано для экспертов.

2. @klutt Но что, если пользователь вводит 0.41, мы должны проверить значения для 0.41, 0.01 ,0.15,1.6, 23, 4.2, «», фу

3. @klutt Просто придирка, cents - 100*(cents/100) такая же, как cents % 100 .

4. @Quimby Я рассматривал это, но я подумал, что так будет понятнее. Но теперь, оглядываясь назад, я согласен, что по модулю лучше.

5. Ну, быстрое исправление было бы чем-то вроде: int i; float f; scanf("%f", amp;f); i = 100*f;

Ответ №2:

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

 #include <stdio.h>
int main(void)
{
    int total_coins = 0;
    int cash_owed = 0;
    printf("Cash owed in cents: ");
    scanf("%d" , amp;cash_owed);

    // Coins from largest to smallest.
    int coins[4]={25,10,5,1};

    for(int i=0;i<4;  i){
        total_coins = cash_owed/coins[i];
        cash_owed%=coins[i];
    }
    // cash_owed contains remainder that cannot be paid with the coins.

    printf("%dn", total_coins);
    return 0;
}
  

Комментарии:

1. Но что, если пользователь вводит 0.41, мы должны проверить значения для 0.41, 0.01 ,0.15,1.6, 23, 4.2, «», фу

2. @lookabove Боюсь, я не понимаю части 1.6, 23, 4.2, «», foo . Пользователь должен ввести значение в центах. Если вы настаиваете на числах с плавающей запятой, используйте их только для ввода и преобразуйте в целые числа раньше. Повторная арифметика с плавающими значениями может привести к потерям.

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

4. @lookabove В этом случае вы можете воспользоваться советом из комментария Клутта под его ответом — ввод с плавающей запятой, но немедленно преобразуйте его в центы.