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