13. Roman to Integer
Difficulty: Easy
Given a roman numeral, convert it to an integer.
Input is guaranteed to be within the range from 1 to 3999.
将一个罗马数字转换为整形数,输入范围在1~3999。
罗马数字的规则:
1.罗马数字有下面七个基本符号:
Ⅰ(1)
Ⅴ(5)
Ⅹ(10)
L(50)
C(100)
D(500)
M(1000)
2.罗马数字无表示零的数。
3.除I、X、C位于大数后作为加数(连用不能超过三个),位于大数前作为减数(只能用一个)外,一般把若干罗马基本数字写在一起,它表示的数字等于各个数字的和。
重写: III(3) XX(20) CC(200)
左减: IX(9) XL(40) CD(400)
右加: VII(7) XI(11) LX(60)
综合前三种方法:xlv(L-X+V,45) LXII(L+X+I+I,62)
4.
V和X 左边的小数字只能用Ⅰ。
L 和C 左边的小数字只能用X。
D 和M 左边的小数字只能用C。
例如:
XIX=10+(10-1)=19
XLV=(50-10)+5=45
MCMXXC=1000+(1000-100)+(100-20)=1980
思路:
1.若当前字符表示的值与上一个字符一样,临时变量加上这个字符
2.若当前比前一个大,临时变量等于当前这个值减去前面记录下的临时变量中的值
3.若当前比前一个小,先将临时变量的值加到结果中,然后开始下一段记录(即,直到当前比前一个小,才把前面计算的临时变量sub加到结果中,更新sub)
int getRomanValue(char s);
int romanToInt(char* s) {
int i;
int lastv,curv,sub,result;
int retint;
int len=strlen(s);
lastv=getRomanValue(s[0]); //前一个字符表示的值
sub=lastv; //临时变量存储将要加到result的值
result=0;
//若当前字符表示的值与上一个字符一样,临时变量加上这个字符
//若当前比前一个大,临时变量等于当前这个值减去前面记录下的临时变量中的值
//若当前比前一个小,先将临时变量的值加到结果中,然后开始下一段记录
for(i=1;i<len;i++)
{
curv=getRomanValue(s[i]);
if(curv==lastv) //当前与前一个相等,sub累积
{
sub+=curv;
}
else if(curv>lastv)
{
sub=curv-sub; //当前比前一个大,sub累积
}
else if(curv<lastv)
{
result+=sub;
sub=curv; //直到当前比前一个小,sub加到结果中,sub更新
}
lastv=curv; //last更新
}
result+=sub; //result存储结果
return result;
}
int getRomanValue(char s)
{
int ret;
if(s=='I')
ret=s-'I'+1; //I表示1
else if(s=='V')
ret=s-'V'+5; //V表示5
else if(s=='X')
ret=s-'X'+10; //X表示10
else if(s=='L')
ret=s-'L'+50; //L表示50
else if(s=='C')
ret=s-'C'+100; //C表示100
else if(s=='D')
ret=s-'D'+500; //D表示500
else if(s=='M')
ret=s-'M'+1000; //M表示1000
else
ret=0;
return ret;
}