Given a roman numeral, convert it to an integer.
Input is guaranteed to be within the range from 1 to 3999.
题目虽短,但是难度还是在那里的。
首先,我们需要明白罗马数字是怎么计数的,当你明白了这个就少走了很多弯路了。
罗马数字是阿拉伯数字传入之前使用的一种数码。罗马数字采用七个罗马字母作数字、即Ⅰ(1)、X(10)、C(100)、M(1000)、V(5)、L(50)、D(500)。记数的方法:
-
相同的数字连写,所表示的数等于这些数字相加得到的数,如 Ⅲ=3;
-
小的数字在大的数字的右边,所表示的数等于这些数字相加得到的数,如 Ⅷ=8、Ⅻ=12;
-
小的数字(限于 Ⅰ、X 和 C)在大的数字的左边,所表示的数等于大数减小数得到的数,如 Ⅳ=4、Ⅸ=9;
-
在一个数的上面画一条横线,表示这个数增值 1,000 倍,如=5000。
那么首先第一件事,就是构建一个最基本的映射,Ⅰ(1)、X(10)、C(100)、M(1000)、V(5)、L(50)、D(500),当然我还是用了自己比较喜欢的map
来构建这样一个词典,但是在用map的过程中,我发现自己竟然有一个非常重要的地方忽略了,就是用下标来取值的时候其类型事实上是mapped_type而不是value_type,只有用
迭代器来取second的值得时候,因此在这里用了find函数,find函数返回根据key值所找到的迭代器,你才会得到value_type,所以我刚开始用它们直接比较的时候一直出错。
然后就是比较大小了,小的就加就好了,大的时候要取大值减小值,这个时候要向前跳一个i=i-2
还好罗马数字大值减小值的时候,只有两位,否则会更加复杂。附代码,做出来就ok。。
1 class Solution { 2 public: 3 int romanToInt(string s) { 4 map<string,int> roman; 5 string tempb,tempf; 6 int r,l; 7 roman["I"]=1; 8 roman["X"]=10; 9 roman["C"]=100; 10 roman["M"]=1000; 11 roman["V"]=5; 12 roman["L"]=50; 13 roman["D"]=500; 14 int result=0; 15 int length=s.length(); 16 if(length==0) return 0; 17 for(int i=length-1;i>=0;){ 18 tempb=s[i]; 19 tempf=s[i-1]; 20 21 auto it=roman.find(tempb); 22 auto itfront=roman.find(tempf); 23 if((*it).second<=(*itfront).second) { 24 result+=(*it).second; 25 i--;} 26 else {result=result+(*it).second-(*itfront).second; 27 i=i-2; 28 } 29 30 } 31 return result; 32 33 34 } 35 };