首先我们可以知道,一个整数,最多由2个罗马数字组成。
思路分析
这个方法能够正确将罗马数字转换为阿拉伯数字的原因在于它遵循了罗马数字的规则,并且对这些规则进行了正确的编码和处理。
罗马数字规则
- 罗马数字由以下字符组成:I, V, X, L, C, D, M,分别对应的阿拉伯数字为:1, 5, 10, 50, 100, 500, 1000。
- 一般情况下,罗马数字表示法从左到右是从大到小累加。例如:VI = 5 + 1 = 6。
- 但是,有些情况下需要用减法来表示,例如:IV = 5 - 1 = 4。这种情况出现在一个较小的数字出现在较大的数字之前。
算法步骤
-
初始化哈希表:
- 使用一个哈希表(map)将罗马数字字符映射到对应的阿拉伯数字值。这样我们可以在O(1)时间复杂度内查找每个字符对应的值。
-
遍历字符串:
- 从左到右遍历罗马数字字符串。
-
处理特殊规则:
- 如果当前字符的值小于下一个字符的值,那么根据罗马数字的规则,当前字符应被减去。例如,IV中的I(1)小于V(5),因此应计算5 - 1。
- 如果当前字符的值大于或等于下一个字符的值,那么直接将其值累加。例如,VI中的V(5)大于I(1),因此应计算5 + 1。
为什么可以得出正确结果
-
哈希表的使用:
- 哈希表允许我们快速找到每个罗马字符对应的阿拉伯数字值,确保了查找操作的高效性和准确性。
-
遍历与比较:
- 通过遍历字符串,并比较当前字符与下一个字符的值,我们可以准确地识别应该进行加法还是减法。这种方法符合罗马数字的规则,从而确保了正确的转换。
-
累加与减法处理:
- 如果遇到需要进行减法的情况(即当前字符值小于下一个字符值),我们在累加当前字符值时进行了正确的调整,即减去当前字符值两次(先加再减),从而正确处理了减法情况。
class Solution {
// 哈希表,用于存储罗马数字字符到阿拉伯数字的映射
map<char, int> hash;
// 函数:初始化哈希表,将罗马数字映射为阿拉伯数字
void getHash() {
hash['I'] = 1;
hash['V'] = 5;
hash['X'] = 10;
hash['L'] = 50;
hash['C'] = 100;
hash['D'] = 500;
hash['M'] = 1000;
}
public:
int romanToInt(string s) {
getHash(); // 初始化哈希表
int num = 0; // 最终结果
int after; // 下一个字符对应的值
// 遍历字符串的每个字符
for (int i = 0; i < s.size(); i++) {
if (i == s.size() - 1) {
// 如果是最后一个字符,直接加上对应的值
num += hash[s[i]];
} else {
// 获取下一个字符的值
after = hash[s[i + 1]];
// 如果当前字符的值小于下一个字符的值
if (hash[s[i]] < after) {
// 根据罗马数字的规则,组合成减法表达式
num += after - hash[s[i]];
// 跳过下一个字符
i++;
} else {
// 当前字符的值大于或等于下一个字符的值,直接加上
num += hash[s[i]];
}
}
}
return num; // 返回结果
}
};