zekaiyang@home:~$

Convert Roman Numerals To Arabic Numerals

Convert Roman numerals to Arabic numerals

leetcode第13题就是罗马数字转阿拉伯数字。这道题目的思路很简单,通常情况下,罗马数字中小的数字在大的数字的右边,所以我们将每个字符视作一个单独的值,若一个数字右侧的数字比它大,则将该数字的符号取反。

举例:X+(−I)+V=10−1+5=14。

所以很容易得到题解:

class Solution {
private:
    unordered_map<char, int> symbolValues = {
        {'I', 1},
        {'V', 5},
        {'X', 10},
        {'L', 50},
        {'C', 100},
        {'D', 500},
        {'M', 1000},
    };
public:
    int romanToInt(string s) {
        int ans = 0;
        int n = s.length();
        for (int i = 0; i < n; ++i) {
            int value = symbolValues[s[i]];
            if (i < n - 1 && value < symbolValues[s[i + 1]]) {
                ans -= value;
            } else {
                ans += value;
            }
        }
        return ans;
    }
};

但是我们存在一个问题,阿拉伯数字更加简便直观,易于理解和书写(通过0-9这十个数字的组合,可以表示任意大的数目,并且可以简单地进行数值计算),罗马它就像一个个单词一样,不同位置可以存在的字母是有规则的,我们如何判断输入的罗马数字的合法性?我们先列举一下它的规则:

基本符号:I, V, X, L, C, D, M(分别对应1, 5, 10, 50, 100, 500, 1000)。
加法规则:符号按从左到右的值递减排列时相加(如 VI = 5 + 1 = 6)。
减法规则:若小值符号出现在大值符号左侧,则相减(如 IV = 5 - 1 = 4),且仅允许以下组合:
  I 可前置 V 或 X(如 IV, IX)。
  X 可前置 L 或 C(如 XL, XC)。
  C 可前置 D 或 M(如 CD, CM)。
重复规则:I, X, C, M 可以重复,最多连续出现三次。V, L, D 不能重复。
顺序规则:符号通常按值从高到低排列。例如:
  正确的:MCXI (1000 + 100 + 10 + 1 = 1111)
  不正确的:IM(虽然 I 在 M 左边,但不符合相减规则,因为 I 只能用于 V 和 X 的左边)

我们可以把它类比成一门语言,它具有有限的符号集 {I, V, X, L, C, D, M},它有组成“词”的规则,