13.罗马数字转整数

  1. 13.罗马数字转整数
    1. 13.1 题目
    2. 13.2 题解
      1. 比较下一数字
    3. 13.3 代码
    4. 13.4 运行结果

13.罗马数字转整数


13.1 题目

罗马数字包含以下七种字符:I,V,X,L,C,D 和 M。

  • 字符 数值
    • I 1
    • V 5
    • X 10
    • L 50
    • C 100
    • D 500
    • M 1000

例如,罗马数字 2 写做 II ,即为两个并列的 1 。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX

这个特殊的规则只适用于以下六种情况:

  • I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
  • X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。
  • C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。

给定一个罗马数字,将其转换成整数。

示例:

  • 示例 1:

    • 输入: s = "III"
    • 输出: 3
  • 示例 2:

    • 输入: s = "IV"
    • 输出: 4
  • 示例 3:

    • 输入: s = "IX"
    • 输出: 9
  • 示例 4:

    • 输入: s = "LVIII"
    • 输出: 58
    • 解释: L = 50, V= 5, III = 3.
  • 示例 5:

    • 输入: s = "MCMXCIV"
    • 输出: 1994
    • 解释: M = 1000, CM = 900, XC = 90, IV = 4.

提示:

  • 1 <= s.length <= 15
  • s 仅含字符 (‘I’, ‘V’, ‘X’, ‘L’, ‘C’, ‘D’, ‘M’)
  • 题目数据保证 s 是一个有效的罗马数字,且表示整数在范围 [1, 3999] 内
  • 题目所给测试用例皆符合罗马数字书写规则,不会出现跨位等情况。IL 和 IM 这样的例子并不符合题目要求,49 应该写作 XLIX,999 应该写作 CMXCIX。关于罗马数字的详尽书写规则,可以参考 罗马数字 - Mathematics

13.2 题解

比较下一数字

// 方法一:比较下一数字
// 判断下一数是否小于当前数决定加上数字还是减去数字 可以提前加上下一数字减少循环
static int RomanToInt(string s)
{
    // 创建一个字典,存储罗马数字字符与对应的整数值的映射关系
    Dictionary<char, int> romanValues = new Dictionary<char, int>
    {
        { 'I', 1 }, // I 对应 1
        { 'V', 5 }, // V 对应 5
        { 'X', 10 }, // X 对应 10
        { 'L', 50 }, // L 对应 50
        { 'C', 100 }, // C 对应 100
        { 'D', 500 }, // D 对应 500
        { 'M', 1000 } // M 对应 1000
    };

    // 初始化结果变量,用于存储最终的整数值
    int result = 0;

    // 遍历输入的罗马数字字符串
    for (int i = 0; i < s.Length; i++)
    {
        // 如果当前字符不是最后一个字符
        if (i + 1 < s.Length)
        {
            // 如果当前字符对应的值大于或等于下一个字符的值
            if (romanValues[s[i]] >= romanValues[s[i + 1]])
            {
                // 将当前字符对应的值加到结果中
                result += romanValues[s[i]];
            }
            else
            {
                // 如果当前字符对应的值小于下一个字符的值
                // 减去当前字符对应的值
                result -= romanValues[s[i]];
                // 并加上下一个字符对应的值
                result += romanValues[s[i + 1]];
                // 跳过下一个字符,因为已经处理过
                i++;
            }
        }
        else
        {
            // 如果当前字符是最后一个字符,直接加上它对应的值
            result += romanValues[s[i]];
        }
    }

    // 返回最终的整数值
    return result;
}

13.3 代码

using System;

class Program
{
    static void Main()
    {
        #region 题目

        // 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。
        // 字符          数值
        // I             1
        // V             5
        // X             10
        // L             50
        // C             100
        // D             500
        // M             1000
        // 例如, 罗马数字 2 写做 II ,即为两个并列的 1 。12 写做 XII ,即为 X + II 。 27 写做  XXVII, 即为 XX + V + II 。
        // 通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。
        // 数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。
        // 这个特殊的规则只适用于以下六种情况:
        // I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
        // X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。 
        // C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。
        // 给定一个罗马数字,将其转换成整数。

        // 示例 1:
        // 输入: s = "III"
        // 输出: 3
        // 示例 2:
        // 输入: s = "IV"
        // 输出: 4
        // 示例 3:
        // 输入: s = "IX"
        // 输出: 9
        // 示例 4:
        // 输入: s = "LVIII"
        // 输出: 58
        // 解释: L = 50, V= 5, III = 3.
        // 示例 5:
        // 输入: s = "MCMXCIV"
        // 输出: 1994
        // 解释: M = 1000, CM = 900, XC = 90, IV = 4.

        // 提示:
        // 1 <= s.length <= 15
        // s 仅含字符 ('I', 'V', 'X', 'L', 'C', 'D', 'M')
        // 题目数据保证 s 是一个有效的罗马数字,且表示整数在范围 [1, 3999] 内
        // 题目所给测试用例皆符合罗马数字书写规则,不会出现跨位等情况。
        // IL 和 IM 这样的例子并不符合题目要求,49 应该写作 XLIX,999 应该写作 CMXCIX 。
        // 关于罗马数字的详尽书写规则,可以参考 罗马数字 - Mathematics 。

        #endregion

        #region 测试

        // 示例 1
        string s1 = "III";
        int result1 = RomanToInt(s1);
        Console.WriteLine($"示例1 输出:{result1}");

        // 示例 2
        string s2 = "IV";
        int result2 = RomanToInt(s2);
        Console.WriteLine($"示例2 输出:{result2}");

        // 示例 3
        string s3 = "IX";
        int result3 = RomanToInt(s3);
        Console.WriteLine($"示例3 输出:{result3}");

        // 示例 4
        string s4 = "LVIII";
        int result4 = RomanToInt(s4);
        Console.WriteLine($"示例4 输出:{result4}");

        // 示例 5
        string s5 = "MCMXCIV";
        int result5 = RomanToInt(s5);
        Console.WriteLine($"示例5 输出:{result5}");

        #endregion
    }

    #region 答案

    // 方法一:比较下一数字
    // 判断下一数是否小于当前数决定加上数字还是减去数字 可以提前加上下一数字减少循环
    static int RomanToInt(string s)
    {
        // 创建一个字典,存储罗马数字字符与对应的整数值的映射关系
        Dictionary<char, int> romanValues = new Dictionary<char, int>
        {
            { 'I', 1 }, // I 对应 1
            { 'V', 5 }, // V 对应 5
            { 'X', 10 }, // X 对应 10
            { 'L', 50 }, // L 对应 50
            { 'C', 100 }, // C 对应 100
            { 'D', 500 }, // D 对应 500
            { 'M', 1000 } // M 对应 1000
        };

        // 初始化结果变量,用于存储最终的整数值
        int result = 0;

        // 遍历输入的罗马数字字符串
        for (int i = 0; i < s.Length; i++)
        {
            // 如果当前字符不是最后一个字符
            if (i + 1 < s.Length)
            {
                // 如果当前字符对应的值大于或等于下一个字符的值
                if (romanValues[s[i]] >= romanValues[s[i + 1]])
                {
                    // 将当前字符对应的值加到结果中
                    result += romanValues[s[i]];
                }
                else
                {
                    // 如果当前字符对应的值小于下一个字符的值
                    // 减去当前字符对应的值
                    result -= romanValues[s[i]];
                    // 并加上下一个字符对应的值
                    result += romanValues[s[i + 1]];
                    // 跳过下一个字符,因为已经处理过
                    i++;
                }
            }
            else
            {
                // 如果当前字符是最后一个字符,直接加上它对应的值
                result += romanValues[s[i]];
            }
        }

        // 返回最终的整数值
        return result;
    }

    #endregion
}

13.4 运行结果

示例1 输出:3
示例2 输出:4
示例3 输出:9
示例4 输出:58
示例5 输出:1994


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏