题目:
Given an integer, convert it to a roman numeral.
Input is guaranteed to be within the range from 1 to 3999.
思路:
首先熟悉一下罗马数字的的对应符号(以下内容参考小榕流光的博客,在此表示感谢):
I (1)V(5)X(10) L(50)C(100)D(500)M(1000)。
技术规则:
1)若干相同数字连写表示的数是这些罗马数字的和,如III=3;
2)小数字在大数字前面表示的数是用大数字减去小数字,例如IV=4;
3)小数字在大数字后面表示的数是用大数字加上小数字,例如VI=6;
组合规则:
1)基本数字I、X、C中的任何一个,自身连用构成数目,或者放在大数的右边连用构成数目,都不能超过三个;放在大数的左边只能用一个;
2)不能把基本数字V、L、D中的任何一个作为小数放在大数的左边采用相减的方法构成数目;放在大数的右边采用相加的方式构成数目,只能使用一个;
3)V和X左边的小数字只能用I;
4)L和C左边的小数字只能用X;
5)D和M左边的小数字只能用C。
我原来的思路是首先计算出输入数字中分别可以分解出多少个基本数字(由七种符号表示),构成相应的字符串,然后再根据组合规则进行相应修改,写出来的AC代码高达60行。后来发现如果把所有需要相减的数也作为基本数来做映射,那么处理程序将大大简化。直接上代码。
代码:
class Solution {
public:
string intToRoman(int num) {
// using array is faster than vector
int nums[13] = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
string roman[13] = {"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"};
int k = 0;
string result;
while(num > 0)
{
if(num >= nums[k])
result += roman[k], num -= nums[k];
else
k++;
}
return result;
}
};