题目
链接: link.
解题思路
按照给定罗马数字字符串的顺序,依次将每个字母对应的整数,加到结果当中即可。其中,有几种情况需要特殊考虑:
1.当前字母为I,且后一位字母为V或X
2.当前字母为X,且后一位字母为L或C
3.当前字母为C,且后一位字母为D或M
为这三种情况,做条件判断即可。
代码
int romanToInt(string s)
{
unordered_map <string, int> dict = { { "I", 1 },{ "V", 5 },{ "X", 10 },{ "L", 50 },{ "C", 100 },{ "D", 500 },
{ "M", 1000 },{ "IV", 4 },{ "IX", 9 },{ "XL", 40 },{ "XC", 90 },{ "CD", 400 },{ "CM", 900 } };
int ret = 0;
int m = s.size();
int i = 0;
while (i < m) {
int temp = 0;
int value = 0;
if ((s[i] == 'I' && i < m - 1 && (s[i + 1] == 'V' || s[i+1] == 'X')) ||
(s[i] == 'X' && i < m - 1 && (s[i + 1] == 'L' || s[i + 1] == 'C')) ||
(s[i] == 'C' && i < m - 1 && (s[i + 1] == 'D' || s[i + 1] == 'M'))) {
char keyTemp[2] = {s[i], s[i + 1]};
string key(keyTemp, 2);
value = dict[key];
i += 2;
} else {
string key;
key.push_back(s[i]);
value = dict[key];
i++;
}
ret += value;
}
return ret;
}
但是这种解法,成绩并不好:
参考了一下评论区大佬的解法,发现有可优化的地方,我们从题目中发现这样一句话:
其实无需去判断上述三种特殊情况,只需要在顺序遍历的时候,如果判断当前位,小于后一位,减去当前位的字母代表的数字即可。
改正后的代码:
int romanToInt(string s)
{
map <char, int> dict = { { 'I', 1 },{ 'V', 5 },{ 'X', 10 },{ 'L', 50 },{ 'C', 100 },{ 'D', 500 }, {'M', 1000} }; // 将哈希map改成了map
int ret = 0;
int m = s.size();
int i = 0;
while (i < m) {
if ((i + 1 < m) && dict[s[i]] < dict[s[i + 1]]) {
ret -= dict[s[i]];
} else {
ret += dict[s[i]];
}
i++;
}
return ret;
}
最终成绩有所改善: