这两道题是罗马数字字符串和整数互相转换,只要理解了罗马数组的构数规则就很好解了,感觉用不到什么特别的算法。
(1) Integer to Roman
罗马数字只有1,5,10,50,100,500,1000,这几个数字,因此,我们可以从大到小遍历,比如2345,2000>1000,得到一个'M',然后变成1345,同样,再减1000,得到"MM",变成345,依次类推即可[1]。
class Solution {
public:
string intToRoman(int num) {
map<int, pair<int, string> > map_data;
map_data.insert(make_pair(0, make_pair(1000, "M")));
map_data.insert(make_pair(1, make_pair(900, "CM")));
map_data.insert(make_pair(2, make_pair(500, "D")));
map_data.insert(make_pair(3, make_pair(400, "CD")));
map_data.insert(make_pair(4, make_pair(100, "C")));
map_data.insert(make_pair(5, make_pair(90, "XC")));
map_data.insert(make_pair(6, make_pair(50, "L")));
map_data.insert(make_pair(7, make_pair(40, "XL")));
map_data.insert(make_pair(8, make_pair(10, "X")));
map_data.insert(make_pair(9, make_pair(9, "IX")));
map_data.insert(make_pair(10, make_pair(5, "V")));
map_data.insert(make_pair(11, make_pair(4, "IV")));
map_data.insert(make_pair(12, make_pair(1, "I")));
string ret;
while(num>0)
for(int i=0;i<13;i++)
{
if(num>=map_data[i].first)
{
num-=map_data[i].first;
ret+=map_data[i].second;
break;
}
}
return ret;
}
};
(2) Roman to Integer
从前往后扫描,用一个临时变量记录分段数字。
如果当前处理的字符对应的值和上一个字符一样,那么临时变量加上这个字符。比如III = 3;
如果当前比前一个大,说明这一段的值应该是当前这个值减去前面记录下的临时变量中的值。比如IIV = 5 – 2;
如果当前比前一个小,那么就可以先将临时变量的值加到结果中,然后开始下一段记录。比如VI = 5 + 1。
以上来自[2]。
class Solution {
public:
int romanToInt(string s) {
map<char,int> m;
m.insert({'I',1});
m.insert({'V',5});
m.insert({'X',10});
m.insert({'L',50});
m.insert({'C',100});
m.insert({'D',500});
m.insert({'M',1000});
int ret=0,tmp=m[s[0]],pre=m[s[0]],cur;
for(int i=1;i<s.size();i++)
{
cur=m[s[i]];
if(cur==pre)
tmp+=cur;
else if(cur<pre)
{
ret+=tmp;
tmp=cur;
}
else
tmp=cur-tmp;
pre=cur;
}
ret+=tmp;
return ret;
}
};
参考:
[1] http://www.2cto.com/kf/201310/253845.html
[2] http://blog.csdn.net/beiyetengqing/article/details/8458778