1.罗马数字的计数规则
罗马数字共有7个 I(1) ,V(5),X(10),C(100),D(500),M(1000)。
a、重复数次:
一个罗马数字重复几次,就表示这个数的几倍。比如: III表示3,XXX表示30。 同一数码最多只能出现三次,如40不可表示为XXXX,而要表示为XL。
例外:由于IV是古罗马神话主神朱庇特(即IVPITER,古罗马字母里没有J和U)的首字,因此有时用IIII代替Ⅳ。
b、右加左减:
在较大的罗马数字的右边记上较小的罗马数字,表示大数字加小数字。在较大的罗马数字的左边记上较小的罗马数字,表示大数字减小数字。比如:VI表示6,IV表示4
c、 左减的数字有限制:
仅限于I、X、C。比如95不可以写成VC,只能是XCV。
左减时不可跨越一个位数(即十的指数相差大小为一)。比如,99不可以用IC(100 - 1)表示,而是用XCIX([100 - 10] + [10 - 1])表示。(等同于阿拉伯数字每位数字分别表示)
左减数字必须为一位,比如8写成VIII,而非IIX。
d、右加数字限制:
不可连续超过三位,比如14写成XIV,而非XIIII。
e、加线乘千:
在罗马数字的上方加上一条横线表示将这个数乘以1000,即是原数的1000倍。
同理,如果上方有两条横线,即是原数的1000000(1000^{2})倍。
2. 代码实现
2.1 将罗马数字转换成十进制数字
int romanToInt(char * s){
int count = 0;
while (*s){
if (*s == 'V') count += 5;
else if (*s == 'L') count += 50;
else if (*s == 'D') count += 500;
else if (*s == 'M') count += 1000; //采用规则,做减法时候数字左边只能是I,X,C;
else if (*s == 'I')
count = (*(s + 1) == 'V' || *(s + 1) == 'X') ? count - 1 : count + 1;
else if (*s == 'X')
count = (*(s + 1) == 'L' || *(s + 1) == 'C') ? count - 10 : count + 10;
else
count = (*(s + 1) == 'D' || *(s + 1) == 'M') ? count - 100 : count + 100; //当左边是I,X,C时候判断是是否存在减去这个数的情况
s++;
}
return count;
}
上述代码将罗马数字从左向右转换成十进制数字。
2.2 将十进制转换成罗马数字
char* intToRoman(int num) {
int numIndex = 0;
int strIndex = 0;
char* result = (char*)malloc(sizeof(char) * 20);
int nums[] = { 1000, 900 , 500, 400, 100, 90, 50, 40, 10, 9 ,5 , 4 , 1 };
char rom[][12] = { "M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I" };
while (num != 0) {
if (num >= nums[numIndex]) {
memcpy(result + strIndex, rom[numIndex], strlen(rom[numIndex]));//将罗马数字放在指针所指向的位置
strIndex += strlen(rom[numIndex]);//指针向后移动
num -= nums[numIndex]; //数字减去已经存方的罗马数字
}
else {
numIndex++;
}
}
*(result + strIndex) = '\0';
return result;
}
上述代码是将数字转换成罗马数字存放的算法,实际使用中针对数字比较小的十进制数