LeetCode OJ:Roman to Integer(转换罗马字符到整数)
Given a roman numeral, convert it to an integer.
Input is guaranteed to be within the range from 1 to 3999.
首先是罗马字符串的特点:
羅馬數字共有7個,即I(1)、V(5)、X(10)、L(50)、C(100)、D(500)和M(1000)。按照下述的規則可以表示任意正整數。需要注意的是罗马数字中没有“0”,與進位制無關。一般認為羅馬數字只用來記數,而不作演算。
重複數次:一個羅馬數字重複幾次,就表示這個數的幾倍。
右加左減:
在較大的羅馬數字的右邊記上較小的羅馬數字,表示大數字加小數字。
在較大的羅馬數字的左邊記上較小的羅馬數字,表示大數字减小數字。
左减的数字有限制,仅限于I、X、C。比如45不可以写成VL,只能是XLV
但是,左減時不可跨越一個位數。比如,99不可以用IC(100 - 1)表示,而是用XCIX([100 - 10] + [10 - 1])表示。(等同於阿拉伯數字每位數字分別表示。)
左減數字必須為一位,比如8寫成VIII,而非IIX。
右加數字不可連續超過三位,比如14寫成XIV,而非XIIII。(見下方“數碼限制”一項。)
加線乘千:
在羅馬數字的上方加上一條橫線或者加上下標的Ⅿ,表示將這個數乘以1000,即是原數的1000倍。
同理,如果上方有兩條橫線,即是原數的1000000(1000^{2})倍。
數碼限制:
同一數碼最多只能出現三次,如40不可表示為XXXX,而要表示為XL。
例外:由於IV是古羅馬神話主神朱庇特(即IVPITER,古羅馬字母裡沒有J和U)的首字,因此有時用IIII代替Ⅳ。
上面的解释是从别处抄的,思路主要是把每一位与前一位进行比较,大于前一位即用当前位减去上一位保存在临时和中,小于就将临时和加到总和中,等于就给临时和加上当前位数值。大妈如下:
1 class Solution { 2 public: 3 int romanToInt(string s) { 4 int prev, curr, result, tmpResult; 5 prev = curr = result = tmpResult = 0; 6 int sz = s.size(); 7 if(sz == 0) 8 return 0; 9 tmpResult = prev = getRoman(s[0]); 10 for(int i = 1; i < sz; ++i){ 11 curr = getRoman(s[i]); 12 if(curr > prev) 13 tmpResult = curr - prev; 14 else if(curr == prev) 15 tmpResult += curr; 16 else{ 17 result += tmpResult; 18 tmpResult = curr; 19 } 20 prev = curr; 21 } 22 return result + tmpResult; 23 } 24 25 int getRoman(char c) 26 { 27 switch(c){ 28 case 'I': 29 return 1; 30 case 'V': 31 return 5; 32 case 'X': 33 return 10; 34 case 'L': 35 return 50; 36 case 'C': 37 return 100; 38 case 'D': 39 return 500; 40 case 'M': 41 return 1000;//题目说了,最多只能到4999,不用取更大的了 42 default: 43 return 0; 44 } 45 } 46 };
java版本的代码如下,只是为了熟悉一下java的使用:
1 public class Solution { 2 public int romanToInt(String s) { 3 int prev, curr, tmpRes, ret; 4 prev = curr = tmpRes = ret = 0; 5 int sz = s.length(); 6 if(sz == 0) 7 return 0; 8 tmpRes = prev = RToI(s.charAt(0)); 9 for(int i = 1; i < sz; ++i){ 10 curr = RToI(s.charAt(i)); 11 if(curr < prev){ 12 ret += tmpRes; 13 tmpRes = curr; 14 }else if(curr > prev){ 15 tmpRes = curr - prev; 16 }else{ 17 tmpRes += curr; 18 } 19 prev = curr; 20 } 21 return ret + tmpRes; 22 } 23 24 public int RToI(char c){ 25 switch(c){ 26 case 'I': 27 return 1; 28 case 'V': 29 return 5; 30 case 'X': 31 return 10; 32 case 'L': 33 return 50; 34 case 'C': 35 return 100; 36 case 'D': 37 return 500; 38 case 'M': 39 return 1000;//给出数字小于5000,无需在大 40 default: 41 return 0; 42 } 43 } 44 }