[leetcode] 12. Integer to Roman

来源:互联网 发布:我知女人心粤语 编辑:程序博客网 时间:2024/06/05 22:35

Given an integer, convert it to a roman numeral.

Input is guaranteed to be within the range from 1 to 3999.

这道题是将阿拉伯数字转化为罗马数字,题目难度为Medium。

题目的关键在罗马数字的规律上,由于对罗马数字的认识仅限于钟表上的几个数字,所以查了下罗马数字的规律(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、M中的任何一个,自身连用构成数字,或者放在大数的右边连用构成数字时,都不能超过三个,放在大数左边只能用一个;
  2. 不能把基本数字V、L、D中的任何一个作为小数放在大数的左边采用相减的方法构成数字,放在大数的右边采用相加的方式构成数字时只能使用一个;
  3. V和X左边的小数字只能用I;
  4. L和C左边的小数字只能用X;
  5. D和M左边的小数字只能用C。

从上面组合规则可以看出,左边有小数的情况是有限的,可以把这些数字也作为基本数字提取出来,这样就多了IV(4)、IX(9)、XL(40)、XC(90)、CD(400)和CM(900)六种基本数字。有了这十三种基本数字的映射关系后,就可以拿初始数字逐个求出每个基本数字之前的系数,也就得到了转化后的罗马数字。具体代码:

class Solution {public:    string intToRoman(int num) {        vector<int> iVal{1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};        vector<string> rVal{"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};        string ret = "";                for(int i=0; i<13; ++i) {            while(num >= iVal[i]) {                ret += rVal[i];                num -= iVal[i];            }        }                return ret;    }};
另外看到还有人直接将个位到千位四位上数字的所有情况都列出来,然后直接得到结果,具体代码:
class Solution {public:    string intToRoman(int num) {        vector<string> M{"", "M", "MM", "MMM"};        vector<string> C{"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"};        vector<string> X{"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"};        vector<string> I{"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"};        return M[num/1000] + C[(num%1000)/100] + X[(num%100)/10] + I[num%10];    }};

0 0
原创粉丝点击