Этот код сложнее, чем должен (и содержит ошибку), так что это не помогает.
Это может помочь пройти пример.Предположим, что 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 );