题目1:
指路:
思路与分析:
本题中涉及到罗马数字与整数的转化,首先或许想到的是switch-case结构。也就是以下代码段。
for (int i = 0; i < s.size(); i++) {
switch (s[i]) {
case 'I' :
ans += 1;
continue;
case 'V' :
ans += 5;
continue;
case 'X' :
ans += 10;
case 'L' :
ans += 50;
continue;
case 'C' :
ans += 100;
continue;
case 'D' :
ans += 500;
continue;
case 'M' :
ans += 1000;
continue;
}
}
但很显然,初步的思路在运行的道路上失败得淋漓尽致。通常情况下,从1到5的表达是“Ⅰ,Ⅱ,Ⅲ,Ⅳ,Ⅴ”很显然,在“Ⅳ”处,左边的“Ⅰ”(一)小于右边的“Ⅴ”(五)。那么得到结论,如果左边的数小于右边的数,那么这个罗马数结合体是为右边的数减去左边的数。那么我们用一个map结构盛放罗马数字与对应的数字。如果两个罗马数字是左边小于右边,那么换算成数字是为右边减去左边,如果是左边大于右边,,那么换算成数字则为相加。
代码:
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;
}
};
题目2:
指路:
代码:
const pair<int, string> valueSymbols[] = {
{1000, "M"},
{900, "CM"},
{500, "D"},
{400, "CD"},
{100, "C"},
{90, "XC"},
{50, "L"},
{40, "XL"},
{10, "X"},
{9, "IX"},
{5, "V"},
{4, "IV"},
{1, "I"},
};
class Solution {
public:
string intToRoman(int num) {
string roman;
for (const auto &[value, symbol] : valueSymbols) {
while (num >= value) {
num -= value;
roman += symbol;
}
if (num == 0) break;
}
return roman;
}
};