В программе C у меня возникают проблемы с отслеживанием кода, который производит римские цифры от 1 до 1000, используя циклы? - PullRequest
0 голосов
/ 12 марта 2019

Я пытаюсь отследить программу на C, которая преобразует целые числа в цифры от 1 до 1000. Я не понимаю, как этот код преобразует каждое число в римскую цифру.Я думаю, что romanNum [i ++] приращения и временные значения делают математику, но я не уверен в том, как.Мне удалось только проследить диапазон петель.

#include <stdio.h>
int main()
{
    int num;
    for (num = 1; num <= 1000 ; ++num) //1000 loop
    {
        int temp = num; //store single values
        char romanNum[1000]; 
        int i = 0; //to increment romanNum[i] //inside because it's getting increment inside the loop
        int j; //for looping separate values
        //1000=M, 500=D, 100=C, 50=L, 10=X, 5=V, 1=I
        while(temp>0) 
        {       
            if(temp>= 1000)//1000 (highest number)=M
            {  
                for(j=0;j<(temp/1000);j++) //0<1 
                romanNum[i++] = 'M'; //1000=M               
            temp = temp - (temp/1000) * 1000; //0
            }
            else if(temp >=500)//999..500
            {   
                if(temp < (500 + 4 * 100))//500..899
                {                   
                    for(j=0;j<(temp/500);j++)
                    romanNum[i++] = 'D';//
                temp = temp - (temp/500) * 500; //0         
                }
                else//900..999
                { 
                    romanNum[i++] = 'C'; 
                    romanNum[i++] = 'M'; 
                temp = temp - (1000-100);  //0
                }
            }
            else if(temp>=100) //499..100
            {   
                if(temp < (100 + 3 * 100))//100..399
                {
                    for(j=0;j<(temp/100);j++)
                    romanNum[i++] = 'C'; //
                temp = temp - (temp/100) * 100;
                }
                else //400..499
                {   
                    romanNum[i++] = 'L';
                    romanNum[i++] = 'D';
                temp = temp - (500-100);
                }
            }
            else if(temp >=50) //99..50
            {
                if(temp < (50 + 4 * 10))//50..89
                {
                    for(j=0;j<(temp/50);j++)
                    romanNum[i++] = 'L';
                temp = temp - (temp/50) * 50;
                }
                else //90..99
                {
                    romanNum[i++] = 'X';
                    romanNum[i++] = 'C';
                temp = temp - (100-10);
                }
            }
            else if(temp >=10)//49..10
            {
                if(temp < (10 + 3 * 10))//10..39
                {
                    for(j=0;j<(temp/10);j++)
                    romanNum[i++] = 'X';
                temp = temp - (temp/10) * 10;//0
                }
                else//40..49
                {
                    romanNum[i++] = 'X';
                    romanNum[i++] = 'L';
                temp = temp - (50-10);
                }
            }
            else if(temp >=5)//9..5
            {
                if(temp < (5 + 4 * 1))//5..8
                {
                    for(j=0;j<(temp/5);j++)
                    romanNum[i++] = 'V';
                temp = temp - (temp/5) * 5;//0
                }
                else//9
                {
                    romanNum[i++] = 'I';
                    romanNum[i++] = 'X';
                temp = temp - (10-1);//0
                }
            }
            else if(temp >=1)//4..1
            {
                if(temp < 4)//1..3
                {               
                    for(j=0;j<(temp/1);j++)
                    romanNum[i++] = 'I';
                temp = temp - (temp/1) * 1;
                }
                else//4
                {   
                    romanNum[i++] = 'I';
                    romanNum[i++] = 'V';
                temp = temp - (5-1);//0
                }
            }
        }
        printf("%d ", num);//1..1000

        for(j=0;j<i;j++)//to print romanNum
        {
            printf("%c",romanNum[j]);//I..M
        }
        printf("\n");
    }//end of 1000 loop

    return 0;

}

1 Ответ

1 голос
/ 13 марта 2019

Этот код сложнее, чем должен (и содержит ошибку), так что это не помогает.

Это может помочь пройти пример.Предположим, что num равно 2798 (этого не будет, поскольку num максимально в 1000 во внешнем цикле, но я думаю, что это значение будет более иллюстративным).Это будет соответствовать римской цифре MMDCCXCVIII:

2000 = MM
 700 = DCC
  90 = XC
   8 = VIII

Помните, что 4 s и 9 s странные:

   4 = IV (1 from 5)
  40 = XL (10 from 50)
 400 = CD (100 from 500)

   9 = IX (1 from 10)
  90 = XC (10 from 100)
 900 = CM (100 from 1000)

Итак, мы начнем с присвоения2798 до temp.Сначала мы должны выяснить, сколько тысяч ('M') должно быть в выводе:

if(temp>= 1000)//1000 (highest number)=M
{  
  for(j=0;j<(temp/1000);j++) //0<1 
    romanNum[i++] = 'M'; //1000=M      

  temp = temp - (temp/1000) * 1000; //0
}

temp больше или равно 1000, поэтому мы вводим forпетля.temp/1000 дает нам 2 (целочисленное деление дает целочисленный результат), поэтому нам нужно записать два 'M' s в romanNum:

romanNum[i++] = 'M';  // this line gets executed twice.

, поэтому мы имеем

romanNum[0] == 'M'
romanNum[1] == 'M'

Затем мы вычитаем это 2000 из 2798, оставляя нам 798 в temp.Затем мы проверяем, является ли этот результат большим или равным 500 ('D'):

else if(temp >=500)//999..500

Так оно и есть, поэтому мы проверяем, не меньше ли оно 900:

  if(temp < (500 + 4 * 100))//500..899

Это так, поэтому нам просто нужно испустить один D:

    for(j=0;j<(temp/500);j++)        // this loop is actually a bit meaningless,
      romanNum[i++] = 'D';           // since temp < 1000 at this point

и вычесть 500 из temp:

temp = temp - (temp/500) * 500;      // again, temp is < 1000, so this
                                     // could be simplified as `temp - 500`

Еслиесли бы было больше 900, нам пришлось бы испустить CM и вычесть 900 из temp:

else//900..999
{ 
  romanNum[i++] = 'C'; 
  romanNum[i++] = 'M'; 
  temp = temp - (1000-100);  //0
}

К этому моменту tempравно 298 и romanNum равно

romanNum[0] == 'M'
romanNum[1] == 'M'
romanNum[2] == 'D'

Теперь мы должны выяснить, сколько оставшихся сотен ('C') нужно ввести в вывод:

else if(temp>=100) //499..100

Еслиtemp меньше 400, тогда нам просто нужно испустить 'C':

if(temp < (100 + 3 * 100))//100..399
{
  for(j=0;j<(temp/100);j++)
    romanNum[i++] = 'C'; //
  temp = temp - (temp/100) * 100;
}

В нашем случае это так, поэтому мы записываем два 'C' s в romanNum и вычитаем 200 с temp, оставляя нас с 98 и

romanNum[0] == 'M'
romanNum[1] == 'M'
romanNum[2] == 'D'
romanNum[3] == 'C'
romanNum[4] == 'C'

В противном случае нам пришлось бы выдавать CD (этот код выдает LD, что не правильно):

else //400..499
{   
  romanNum[i++] = 'L';
  romanNum[i++] = 'D';
  temp = temp - (500-100);
}

Вы должны быть в состоянии выяснить остаток здесь.Опять же, 4 с и 9 с являются особыми случаями.

Для чего этот код может быть сделан намного проще:

while ( temp >= 1000 )
{
  romanNum[i++] = 'M';
  temp -= 1000;
}

if ( temp >= 900 )
{
  romanNum[i++] = 'C';
  romanNum[i++] = 'M';
  temp -= 900;
}

if ( temp >= 500 )
{
  romanNum[i++] = 'D';
  temp -= 500;
}

if ( temp >= 400 )
{
  romanNum[i++] = 'C';
  romanNum[i++] = 'D';
  temp -= 400;
}

while ( temp >= 100 )
{
  romanNum[i++] = 'C';
  temp -= 100;
}

if ( temp >= 90 )
{
  romanNum[i++] = 'X';
  romanNum[i++] = 'C';
  temp -= 90;
}

if ( temp >= 50 )
{
  romanNum[i++] = 'L';
  temp -= 50;
}

if ( temp >= 40 )
{
  romanNum[i++] = 'X';
  romanNum[i++] = 'L';
  temp -= 40;
}

while ( temp >= 10 )
{
  romanNum[i++] = 'X';
  temp -= 10;
}

if ( temp >= 9 )
{
  romanNum[i++] = 'I';
  romanNum[i++] = 'X';
  temp -= 9;
}

if ( temp >= 5 )
{
  romanNum[i++] = 'V';
  temp -= 5;
}

it ( temp >= 4 )
{
  romanNum[i++] = 'I';
  romanNum[i++] = 'V';
  temp -= 4;
}

while ( temp >= 1 )
{
  romanNum[i++] = 'I';
  temp--;
}

romanNum[i] = 0;
printf( "%s\n", romanNum );
...