一、问题描述
Given an integer, convert it to a roman numeral.
Input is guaranteed to be within the range from 1 to 3999.
题意很简单,但是首先要了解罗马数字的表示方法,百度百科中与本题有关的描述有:
罗马数字采用七个罗马字母作数字、即Ⅰ(1)、X(10)、C(100)、M(1000)、V(5)、L(50)、D(500)。记数的方法:
- 相同的数字连写,所表示的数等于这些数字相加得到的数,如 Ⅲ=3;
- 小的数字在大的数字的右边,所表示的数等于这些数字相加得到的数,如 Ⅷ=8、Ⅻ=12;
- 小的数字(限于 Ⅰ、X 和C)在大的数字的左边,所表示的数等于大数减小数得到的数,如 Ⅳ=4、Ⅸ=9;
贴一个转换表有助理解
二、解题思路
根据罗马数字的计数方法,可以总结出4000以内的数的记数规律如下表:
由表可以看出每个数量级有相同的规律,只是字母不同。对于不同的数量级,I、X、C、M是相互等价的,V、L、D是相互等价的,X、C、M是相互等价的,把它们存储在一个4*3的二维数组中,然后对数字的每位逐个判断:
- 如果该位数字小于等于3,则是按“相同的数字连写,所表示的数等于这些数字相加得到的数”的规则记数
- 如果该位数字等于4,则是按
“小数在大数左边,所表示的数等于大数减小数得到的数”的规则记数 - 如果该位数字为5~8,则是按“小的数字在大的数字的右边,所表示的数等于这些数字相加得到的数
- 如果该位数字等于9,在情况与2类似,但字母选择不同
三、C++代码
class Solution {
public:
string intToRoman(int num) {
string s;
char matrix[4][3] = {
{'I', 'V', 'X'},
{'X', 'L', 'C'},
{'C', 'D', 'M'},
{'M'},
};
for (int i = 3; i >= 0; i--) {
int bit = pow(10, i);
int number_of_bit = num / bit;
if (number_of_bit == 0) {
continue;
}
if (number_of_bit <= 3) {
while(number_of_bit--) {
s += matrix[i][0];
}
} else if (number_of_bit == 4) {
s = s + matrix[i][0] + matrix[i][1];
} else if (number_of_bit <= 8) {
number_of_bit -= 5;
s += matrix[i][1];
while(number_of_bit--) {
s += matrix[i][0];
}
} else {
s = s + matrix[i][0] + matrix[i][2];
}
num = num % bit;
}
return s;
}
};