問(wèn)題描述:
Given a roman numeral, convert it to an integer.
Input is guaranteed to be within the range from 1 to 3999.
分析:
這道題需要了解羅馬數(shù)字是什么,包含哪些數(shù)字俊性。
1能曾、相同的數(shù)字連寫威彰,所表示的數(shù)等于這些數(shù)字相加得到的數(shù)氛悬,如:Ⅲ = 3克锣;
2甘有、小的數(shù)字在大的數(shù)字的右邊俄占,所表示的數(shù)等于這些數(shù)字相加得到的數(shù)管怠, 如:Ⅷ = 8;Ⅻ = 12缸榄;
3渤弛、小的數(shù)字,(限于Ⅰ甚带、X 和C)在大的數(shù)字的左邊她肯,所表示的數(shù)等于大數(shù)減小數(shù)得到的數(shù),如:Ⅳ= 4鹰贵;Ⅸ= 9晴氨;
4、正常使用時(shí)碉输,連寫的數(shù)字重復(fù)不得超過(guò)三次籽前。(表盤上的四點(diǎn)鐘“IIII”例外)
5、在一個(gè)數(shù)的上面畫一條橫線敷钾,表示這個(gè)數(shù)擴(kuò)大1000倍枝哄。
有幾條須注意掌握:
1、基本數(shù)字Ⅰ阻荒、X 挠锥、C 中的任何一個(gè),自身連用構(gòu)成數(shù)目侨赡,或者放在大數(shù)的右邊連用構(gòu)成數(shù)目蓖租,都不能超過(guò)三個(gè);放在大數(shù)的左邊只能用一個(gè)羊壹。
2蓖宦、不能把基本數(shù)字V 、L 舶掖、D 中的任何一個(gè)作為小數(shù)放在大數(shù)的左邊采用相減的方法構(gòu)成數(shù)目球昨;放在大數(shù)的右邊采用相加的方式構(gòu)成數(shù)目尔店,只能使用一個(gè)眨攘。
3主慰、V 和X 左邊的小數(shù)字只能用Ⅰ。
4鲫售、L 和C 左邊的小數(shù)字只能用X共螺。
5、D 和M 左邊的小數(shù)字只能用C情竹。
思路:
自己的方法:
基本思路就是從右往左讀字符串藐不,如果小于當(dāng)前的number,就用number減掉它秦效,否則加上它雏蛮。
首先得需要一個(gè)函數(shù)來(lái)將羅馬數(shù)字轉(zhuǎn)換成對(duì)應(yīng)的阿拉伯?dāng)?shù)字,或者新建一個(gè)字典用來(lái)存放對(duì)應(yīng)關(guān)系阱州。
根據(jù)以上思路挑秉,代碼如下:
public int romanToInt(String s) {
int number = 0;
for(int i=s.length()-1; i>=0; i--){
char c = s.charAt(i);
int n = mapping(c);
if(n < number) number -= n;
else number += n;
}
return number;
}
運(yùn)行之后發(fā)現(xiàn)有錯(cuò)誤:
上面的代碼沒(méi)有考慮到兩個(gè)一樣的數(shù)字連著的情況,所以導(dǎo)致加了第一個(gè)X之后苔货,本來(lái)應(yīng)該再加X(jué)卻減了X犀概。
因此,需要對(duì)上面的代碼進(jìn)行修改夜惭。
public int romanToInt(String s) {
int number = mapping(s.charAt(s.length()-1));
int right = number;
for(int i=s.length()-2; i>=0; i--){
int left = mapping(s.charAt(i));
if(left < right) number -= left;
else number += right;
right = left;
}
return number;
}
加入了一個(gè)right變量姻灶,記錄右邊的數(shù)字,通過(guò)判斷左右兩個(gè)數(shù)的大小進(jìn)行增減操作诈茧。
他人的方法:
我是由右向左的产喉,跟右邊的數(shù)作比較,看了別人的代碼是由左向右的若皱,具體的比較方式分為跟左邊和右邊的數(shù)比較兩種方式镊叁。由此看來(lái),還有其他三種方法走触。
方法二:
public int romanToInt(String s) {
int number = 0;
for(int i=s.length()-1; i>=0; i--){
int n= mapping(s.charAt(i));
if(i==0 || n <= mapping(s.charAt(i-1))) number += n;
else number += n - 2*mapping(s.charAt(i-1));
}
return number;
}
從右往左晦譬,跟左邊數(shù)比較,如果小于等于左邊數(shù)互广,加上當(dāng)前數(shù)字敛腌;如果大于左邊數(shù),就加上當(dāng)前數(shù)字減去兩倍的左邊的數(shù)惫皱,用來(lái)抵消接下來(lái)多加上的左邊數(shù)像樊。
方法三:
public int romanToInt(String s) {
int number = 0;
for(int i=0; i<s.length(); i++){
int n= mapping(s.charAt(i));
if(i==0 || n <= mapping(s.charAt(i-1))) number += n;
else number += n - 2*mapping(s.charAt(i-1));
}
return number;
}
方法四:
public int romanToInt(String s) {
int number = 0;
for(int i=0; i<s.length(); i++){
int n= mapping(s.charAt(i));
if(i==s.length()-1 || n >= mapping(s.charAt(i+1))) number += n;
else number -= n;
}
return number;
}
方法三和方法四都是從左至右的,分別與左邊和右邊的數(shù)進(jìn)行比較旅敷。