解法一:
常用的if造火箭解法,就是将大数字写在前面,然后使用if来不断的排除来进行求解,这里直接贴出代码,就不进行讲解了。
class Solution {
public String intToRoman(int num) {
String s = "";
while(num > 0){
if(num >= 1000){
s += "M";
num -= 1000;
}else if(num >= 900){
s += "CM";
num -= 900;
}else if(num >= 500){
s += "D";
num -= 500;
}else if(num >= 400){
s += "CD";
num -= 400;
}else if(num >= 100){
s += "C";
num -= 100;
}else if(num >= 90){
s += "XC";
num -= 90;
}else if(num >= 50){
s += "L";
num -= 50;
}else if(num >= 40){
s += "XL";
num -= 40;
}else if(num >= 10){
s += "X";
num -= 10;
}else if(num >= 9){
s += "IX";
num -= 9;
}else if(num >= 5){
s += "V";
num -= 5;
}else if(num >= 4){
s += "IV";
num -= 4;
}else if(num >= 1){
s += "I";
num -= 1;
}
}
return s;
}
}
解法二
将罗马数字和对应的阿拉伯数字对应起来,然后从大到小依次相减,知道减为0即可,这里我们通常会想到用map来存储相对应的键值对,但是map会进行自动排序,并且是从小到大的去排序内部的数字,而unorderd_map不会进行排序,但是我们使用map的情况一般来说是想通过某一个关键字来快速找出相对应的数,而本题只需要将罗马数字和阿拉伯数字对应起来即可,所以我们这里也可以使用pair来存储键值对。
- std::pair<int, string> 数组的内存和时间开销都相对较小。对于小规模数据集,不需要频繁查找或插入,数组的线性遍历开销比 map 更低。
- 使用pair也可以对两个不同类型的数据进行相互关联,并且我们不需要对其进行查找,只需要遍历一遍就行
string intToRoman(int num) {
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"}
};
string roman;
for (const auto &[value, symbol] : valueSymbols) {
while (num >= value) {
num -= value;
roman += symbol;
}
if (num == 0) {
break;
}
}
return roman;
}
- 在这段代码中,还使用了范围基for循环,这种写法在C++11中被引用,可以大大简化遍历容器(比如数组、vector)中所有元素的代码。
- 还引入了结构化绑定,这种写法在C++17中被引用,它允许将对象(本题中为pair)解构为多个变量,可以直接使用这些变量,而不需要显式访问对象的成员。语法需要使用auto关键字,形式为:
auto &[a, b] = pair_object;
其中&表示引用,[a, b]表示将对象解构为a和b两个变量,在后续操作中可以直接对a,b进行操作,本题中将valueSymbols中的变量解构为value和symbol两个变量