读题心路历程:看到这道题之后,感觉和之前的12题整数转罗马数字应该是异曲同工之妙的。第一个想法是能不能像12题一样,利用贪心算法的思想,但是感觉怪怪的,毕竟是字符串,没办法用最大的数字去反过来表示它。
所以我想到利用Map,遍历字符串的时候,发现有出现在Map里的字符串,就找到对应的整数,然后整数相加,需要注意的有从左遍历的时候如果出现左边的数字小于右边的数字,这个时候就将这两个字符算成一个字符,然后在Map里边找该字符对应的数字,找到就把数字相加,然后在字符串 s 中删除这个字符并且,i--;找不到就一个一个字符找。
具体代码:
int romanToInt(string s) {
int num = 0;
//建立一个Map容器,存例子
map<string, int> list = { {"M",1000} ,
{"CM",900} ,
{"D",500} ,
{"CD",400} ,
{"C",100} ,
{"XC",90} ,
{"L",50} ,
{"XL",40} ,
{"X",10} ,
{"IX",9} ,
{"V",5} ,
{"IV",4} ,
{"I",1} } ;
//遍历字符串s
for (auto i = 0; i < s.size(); i++)
{
//在遍历字符串s的时候,建立一个临时变量,用来存放相邻的两个字符,为了在Map映射中找900、90、40、4这种特例数字。
string curRes;
curRes.push_back(s[i]);
curRes.push_back(s[i+1]);
//这是如果遍历的过程中找到了特例的数字,就把特例数字加到num上,然后在原s里删除掉这两个,因为删除了两个,所以i的值也应该变一变,应该减掉1,这样在下次遍历的时候才能续上之前的字符串s。
if (list.find(curRes) != list.end()) {
num += list[curRes];
s.erase(i,2);
i--;
}
//没有特殊数字,就正常一个一个遍历就行。遍历出的数字加上就行。
else
{
string tmpStr;
tmpStr.push_back(s[i]);
num += list[tmpStr];
}
}
return num;
}