Почему я не могу заменить переменную цикла for случайной буквой? - PullRequest
1 голос
/ 24 сентября 2019

Я писал конвертер целых чисел в римские.На этот раз правильный.

Попытка решить проблему печати 900-х, 90-х и 9-х годов;Я написал цикл for (длится только один цикл, поскольку его целью было предотвратить печать CMCMCMCM вместо CM) внутри цикла while.Но для переменной цикла for я использовал то же самое «n», что и «n» в цикле while, не замечая этого.

Пробежал, работал нормально;затем заметил предполагаемую ошибку.Поменял его местами с «A», вставил «A» в список int cd, cl, ......AAAaa, и в результате возникла путаница с полностью несвязанными номерами.

Я не понимаю, как код может правильно работать с повторно используемой переменной цикла, но не может работать с новой.

#include<stdio.h>
int main()
{
    int num, m, c, d, l, x, v, i, n, cm, cd;
    printf("Enter Number: ");
    scanf_s("%d", &num);
        m = num / 1000;
        d = (num % 1000) / 500;
        c = (num % 500) / 100;
        l = (num % 100) / 50;
        x = (num % 50) / 10;
        v = (num % 10) / 5;
        i = (num % 5);
        n = m + d + c + l + x + v + i;
        while (n > 0)
        {
            {
                for (m; m > 0; m--)
                {
                    printf("M");
                }
            }
            {
                for (n=1; n>0; n--)
                {
                    if (num%1000>=900)
                    {
                        printf("CM");
                        d = d - 1;
                        c = c - 4;
                        num = num - 900;
                    }
                }
            }
            {
                for (d; d > 0; d--)
                    printf("D");
            }
            {
                for (n = 1; n > 0; n--)
                {
                    if (num % 500 >= 400)
                    {
                        printf("CD");
                        c = c - 4;
                    }
                }

            }
            {
                for (c; c > 0; c--)
                    printf("C");
            }
            {
                for (l; l > 0; l--)
                    printf("L");
            }
            {
                for (x; x > 0; x--)
                    printf("X");
            }
            {
                for (v; v > 0; v--)
                    printf("V");
            }
            {
                for (i; i > 0; i--)
                    printf("I");
            }
            n--;
        }
        return 0;
}

Имейте в виду, что циклы for для 900, 400 и т. Д. Не завершены, как я заметил после написания одиночного цикла 900.

1 Ответ

1 голос
/ 24 сентября 2019

Сначала вы вычисляете количество каждой буквы на выходе.Затем у вас есть цикл while, работающий с n, уменьшающимся до 0, т.е. тело цикла запускается n раз.Внутри цикла у вас есть серия циклов for, по одной на каждую букву.Если вы пропустите циклы for, использующие n, вы сделаете следующее:

  • Рассчитайте количество каждой буквы в выводе: m, d, c,и т.д., а также n, которое представляет собой общее количество букв (в аддитивной записи).
  • Повтор n раз:
    • Печать M, m раз.
    • Печать D, d раз.
    • и т. Д.

В результате получается, что без внутренних циклов, которые изменяют n, вы печатаете результат много раз.

Правильный алгоритм для печати римских цифр в аддитивной нотации (4 - IIII и т. д.):

  • Рассчитатьm, d, c и т. Д.
  • Печать M, m раз.
  • Печать D, d раз.
  • и т. Д.

Без циклов for, которые изменяют n, вы повторяете правильный алгоритм n раз:

while (n > 0) {
    … /* code that doesn't modify n and prints the desired output */
    n--;
}

С циклами for, которые изменяютn, вы устанавливаете n в 0 внутри тела бецикл le, поэтому n-- в конце тела цикла устанавливает n в -1, и цикл while завершается после первой итерации.

while (n > 0) {
    … /* some code */
    for (n = 1; n > 0; n--) {
        … /* more core */
    }
    /* On exit of this for loop, the value of n is 0. */
    … /* more code that doesn't modify n */
    n--;
}

Исправление простое: удалите цикл while, так как вы всегда хотите выполнить его тело ровно один раз.Удалите подсчет общего количества букв для печати: это не нужно.Ваши циклы for, использующие n, также выполняют свое тело ровно один раз, поэтому они также бесполезны.Вот результат (я сделал унификацию отступов и удалил ненужные скобки, но в остальном я не пытался улучшить программу):

#include<stdio.h>
int main()
{
    int num, m, c, d, l, x, v, i, cm, cd;
    printf("Enter Number: ");
    scanf("%d", &num);
    m = num / 1000;
    d = (num % 1000) / 500;
    c = (num % 500) / 100;
    l = (num % 100) / 50;
    x = (num % 50) / 10;
    v = (num % 10) / 5;
    i = (num % 5);
    for (m; m > 0; m--)
    {
        printf("M");
    }
    if (num%1000>=900)
    {
        printf("CM");
        d = d - 1;
        c = c - 4;
        num = num - 900;
    }
    for (d; d > 0; d--)
        printf("D");
    if (num % 500 >= 400)
    {
        printf("CD");
        c = c - 4;
    }
    for (c; c > 0; c--)
        printf("C");
    for (l; l > 0; l--)
        printf("L");
    for (x; x > 0; x--)
        printf("X");
    for (v; v > 0; v--)
        printf("V");
    for (i; i > 0; i--)
        printf("I");
    return 0;
}
...