在 C 程序中,我无法跟踪使用循环生成从 1 到 1000 的罗马数字的代码?
In C program, I am having trouble tracing a code that produces roman numerals from 1 to 1000 using loops?
我正在尝试跟踪一个 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;
}
这段代码比它需要的更复杂(并且包含一个错误),所以这没有帮助。
通过示例可能会有所帮助。让我们假设 num
是 2798
(不会是因为 num
在最外层循环中在 1000
处达到最大值,但我认为这个值将更具说明性)。这将对应于罗马数字 MMDCCXCVIII
:
2000 = MM
700 = DCC
90 = XC
8 = VIII
记住 4
和 9
很奇怪:
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'
到romanNum
:
romanNum[i++] = 'M'; // this line gets executed twice.
所以我们有
romanNum[0] == 'M'
romanNum[1] == 'M'
然后我们从 2798
中减去 2000
,在 temp
中留下 798
。然后我们检查该结果是否大于或等于 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
并从 temp
中减去 500:
temp = temp - (temp/500) * 500; // again, temp is < 1000, so this
// could be simplified as `temp - 500`
如果大于900
,我们将不得不发出CM
并从[=34中减去900
=]:
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'
写入 romanNum
并从 temp
中减去 200
,留下 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
s 和 9
s 是特例。
对于它的价值,这段代码可以变得很多更简单:
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 );
我正在尝试跟踪一个 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;
}
这段代码比它需要的更复杂(并且包含一个错误),所以这没有帮助。
通过示例可能会有所帮助。让我们假设 num
是 2798
(不会是因为 num
在最外层循环中在 1000
处达到最大值,但我认为这个值将更具说明性)。这将对应于罗马数字 MMDCCXCVIII
:
2000 = MM
700 = DCC
90 = XC
8 = VIII
记住 4
和 9
很奇怪:
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'
到romanNum
:
romanNum[i++] = 'M'; // this line gets executed twice.
所以我们有
romanNum[0] == 'M'
romanNum[1] == 'M'
然后我们从 2798
中减去 2000
,在 temp
中留下 798
。然后我们检查该结果是否大于或等于 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
并从 temp
中减去 500:
temp = temp - (temp/500) * 500; // again, temp is < 1000, so this
// could be simplified as `temp - 500`
如果大于900
,我们将不得不发出CM
并从[=34中减去900
=]:
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'
写入 romanNum
并从 temp
中减去 200
,留下 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
s 和 9
s 是特例。
对于它的价值,这段代码可以变得很多更简单:
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 );