题目
七个不同的符号代表罗马数字,其值如下:
符号 | 值 |
---|---|
I | 1 |
V | 5 |
X | 10 |
L | 50 |
C | 100 |
D | 500 |
M | 1000 |
罗马数字是通过添加从最高到最低的小数位值的转换而形成的。将小数位值转换为罗马数字有以下规则:
- 如果该值不是以 4 或 9 开头,请选择可以从输入中减去的最大值的符号,将该符号附加到结果,减去其值,然后将其余部分转换为罗马数字。
- 如果该值以 4 或 9 开头,使用 减法形式,表示从以下符号中减去一个符号,例如 4 是 5 (
V
) 减 1 (I
):IV
,9 是 10 (X
) 减 1 (I
):IX
。仅使用以下减法形式:4 (IV
),9 (IX
),40 (XL
),90 (XC
),400 (CD
) 和 900 (CM
)。 - 只有 10 的次方(
I
,X
,C
,M
)最多可以连续附加 3 次以代表 10 的倍数。你不能多次附加 5 (V
),50 (L
) 或 500 (D
)。如果需要将符号附加4次,请使用 减法形式。
给定一个整数,将其转换为罗马数字。
示例 1:
输入:num = 3749
输出: "MMMDCCXLIX"
解释:
3000 = MMM 由于 1000 (M) + 1000 (M) + 1000 (M) 700 = DCC 由于 500 (D) + 100 (C) + 100 (C) 40 = XL 由于 50 (L) 减 10 (X) 9 = IX 由于 10 (X) 减 1 (I) 注意:49 不是 50 (L) 减 1 (I) 因为转换是基于小数位
示例 2:
输入:num = 58
输出:"LVIII"
解释:
50 = L 8 = VIII
示例 3:
输入:num = 1994
输出:"MCMXCIV"
解释:
1000 = M 900 = CM 90 = XC 4 = IV
提示:
1 <= num <= 3999
代码展示
class Solution {
public:
string intToRoman(int num) {
std::vector<std::pair<int, std::string>> romanMap = {
{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"}
};
std::string result = "";
// 使用 while 循环处理整数
while (num > 0) {
for (const auto& [value, symbol] : romanMap) {
if (num >= value) {
result += symbol;
num -= value;
break;
}
}
}
return result;
}
};
代码逐行解释
-
定义映射关系:
std::vector<std::pair<int, std::string>> romanMap = { {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"} };
- 创建一个
vector
,其中每个元素是一个pair
,第一个元素是整数值,第二个元素是对应的罗马数字字符串。
- 创建一个
-
初始化结果字符串:
std::string result = "";
-
使用
while
循环处理整数:while (num > 0) { for (const auto& [value, symbol] : romanMap) { if (num >= value) { result += symbol; num -= value; break; } } }
- 使用
while
循环,只要num
大于 0,就继续处理。 - 内部使用
for
循环遍历romanMap
,找到第一个小于等于num
的值。 - 将对应的罗马数字字符串添加到
result
中。 - 从
num
中减去对应的整数值。 - 使用
break
跳出内层循环,继续处理下一个值。
- 使用
for (const auto& [value, symbol] : romanMap) {
-
for
循环:for
循环用于遍历romanMap
中的每一个元素。romanMap
是一个std::vector<std::pair<int, std::string>>
类型的向量。
-
const auto&
:const auto&
是一种常用的语法,用于引用当前迭代的元素,避免不必要的复制。const
表示我们不打算修改这些值。auto
让编译器自动推导类型。&
表示我们使用引用,而不是复制。
-
结构化绑定:
[value, symbol]
是结构化绑定的语法。value
和symbol
分别绑定到std::pair<int, std::string>
中的第一个和第二个元素。value
绑定到int
类型的值。symbol
绑定到std::string
类型的值。
等价的传统写法
如果你不熟悉结构化绑定,可以使用传统的写法来理解:
for (const auto& pair : romanMap) {
int value = pair.first;
std::string symbol = pair.second;
if (num >= value) {
result += symbol;
num -= value;
break;
}
}
for (const auto& pair : romanMap)
for
循环:这是一个范围基的for
循环,用于遍历romanMap
中的每一个元素。const auto&
:const
表示我们不打算修改pair
。auto
让编译器自动推导pair
的类型。&
表示我们使用引用,而不是复制。这样可以提高性能,因为我们不需要每次都复制pair
。
2. int value = pair.first;
pair.first
:pair
是一个std::pair<int, std::string>
类型的对象。pair.first
是pair
中的第一个元素,类型为int
。- 我们将
pair.first
的值赋给value
变量。
3. std::string symbol = pair.second;
pair.second
:pair
是一个std::pair<int, std::string>
类型的对象。pair.second
是pair
中的第二个元素,类型为std::string
。- 我们将
pair.second
的值赋给symbol
变量。
4. if (num >= value)
- 条件判断:检查当前的
num
是否大于或等于value
。- 如果
num
大于或等于value
,则进入if
语句块。
- 如果
5. result += symbol;
- 字符串拼接:将
symbol
添加到result
字符串的末尾。result
是一个std::string
,用于存储最终的罗马数字字符串。
6. num -= value;
- 减少
num
:从num
中减去value
。- 这一步是为了处理剩下的部分,以便下一次循环继续处理剩余的值。
7. break;
- 跳出循环:一旦找到一个匹配的罗马数字并处理完当前部分,跳出内层循环。
- 这样可以确保每次只处理一个最大的匹配部分,然后继续处理剩余的部分。
标签:std,romanMap,--,symbol,value,力扣,num,pair,解析 From: https://blog.csdn.net/wxtg1921/article/details/143452065