12. 整数转罗马数字

罗马数字由 7 个不同的单字母符号组成,每个符号对应一个具体的数值。此外,减法规则(如问题描述中所述)给出了额外的 6 个复合符号。这给了我们总共 13 个独特的符号(每个符号由 1 个或 2 个字母组成),如下图所示。

fig1

我们用来确定罗马数字的规则是:对于罗马数字从左到右的每一位,选择尽可能大的符号值。

根据罗马数字的唯一表示法,为了表示一个给定的整数 \(\textit{num}\),我们寻找不超过 \(\textit{num}\)的最大符号值,将 \(\textit{num}\) 减去该符号值,然后继续寻找不超过 \(\textit{num}\) 的最大符号值,将该符号拼接在上一个找到的符号之后,循环直至 \(\textit{num}\)\(0\)。最后得到的字符串即为 \(\textit{num}\) 的罗马数字表示。

可以建立一个数值-符号对的列表,按数值从大到小排列。遍历其中的每个数值-符号对,若当前数值 \(\textit{value}\) 不超过\(\textit{num}\),则从\(\textit{num}\)中不断减去\(\textit{value}\),直至 \(\textit{num}\)小于 \(\textit{value}\),然后遍历下一个数值-符号对。若遍历中 \(\textit{num}\)\(0\) 则跳出循环。

pair<int,string> mp[]={
    {1000, "M"},
    {900,  "CM"},
    {500,  "D"},
    {400,  "CD"},
    {100,  "C"},
    {90,   "XC"},
    {50,   "L"},
    {40,   "XL"},
    {10,   "X"},
    {9,    "IX"},
    {5,    "V"},
    {4,    "IV"},
    {1,    "I"},
};

class Solution {
public:
    string intToRoman(int num) {
        string res;
        for(auto &[value,symbol] : mp)
        {
            while(num >= value)
            {
                num -= value;
                res += symbol;
            }
            if(num == 0) break;
        }
        return res;
    }
};
posted @ 2021-06-04 12:01  Dazzling!  阅读(47)  评论(0编辑  收藏  举报