编写一个将整数 n(1≤n≤9999)转化成罗马数字表示的程序。程序运行的结果如图 25-1 所示,将
1~22 的数字都转换为罗马数字,并显示出来。
整数 n(1≤n≤9999)与罗马数字表示有以下对应关系:1000 用一个字符 m 来表示,有几个 1000 就用几个 m 来表示;900 用两个字符 cm 来表示;500 用一个字符 d 来表示;400 用两个字符 cd 来表示; 100 用一个字符 c 来表示;有几个 100 就用几个 c 来表示; 90 用两个字符 xc 来表示;50 用一个字符 l 来表示;40 用两个字符 xl 来表示;10 用一个字符 x 来表示;有几个 10 就用几个 x 来表示;9 用两个字符 iv 来表示;5 用一个字符 v 来表示;4 用两个字符 iv 来表示;1 用一个字符 i 来表示;有几个 1 就用几个 i 来表示。
为了便于程序处理,将阿拉伯数与对应的罗马数字表示分存在两个数组中。转换时,从尽可
能大的数开始考察,要转换的罗马字符能被当前考察的数相减后仅大于等于 0 的次数,就是该考
察数所对应的罗马数字可连续出现的次数。例如数 23,能连续减 10 两次仅大于等于 0,能连续减
1 三次仅大于等于 0,所以其罗马数字有两个字符 x 和 3 个字符 i,即 xxiii。
另外,程序将要转换的整数作为程序的参数。如只有一个参数,表示 1 至该数范围内的整数
转换成罗马数字,如有两个参数,表示该两数范围内的整数转换成罗马数字。
程序还能检查参数的合理性,并将完成转换的工作和检查的工作分别由两个函数完成。
#include
#define ROWS 4
#define COLS 4
int nums[ROWS][COLS]={{1000,1000,1000,1000},{900,500,400,100},{90,50,40,10},{9,5,4,1}};
char *roms[ROWS][COLS]={{"m","m","m","m"},{"cm","d","cd","c"},{"xc","l","xl","x"},{"ix","v","iv","i"}};void checknum(int val)/*检查参数合理性*/
{if(val<1||val>9999){printf("The number must be in range 1..9999.\n");exit(0);}
}
void to_roman(int decimal,char roman[ ])/*将整数转换成罗马数字表示*/
{int power,index;roman[0]='\0';for(power=0;power=nums[power][index]){strcat(roman,roms[power][index]);decimal-=nums[power][index];}}int main(int argc,char *argv[ ])
{int low,high;char roman[25];if(argc<2){printf("Usage:roman decimal_number\n");/*运行程序需带整数参数*/exit(0);}high=low=atoi(argv[1]);/*将第一个参数转换成整数*/checknum(low);if(argc>2){/*带两个参数*/high=atoi(argv[2]);checknum(high);if(low>high){low=high;high=atoi(argv[1]);}}elselow=1;for(;low<=high;low++){to_roman(low,roman);printf("%d\t%s\n",low,roman);}return 0;
}
程序使用带命令行参数的 main 函数,将 1~n 的所有数都转换为罗马数字并输出。修改某些
语句,也可以实现仅转换一个整数的功能。