题目:
分析
思路一:由于是在有限的数字中将罗马数字转换为阿拉伯数字所以可以采取列表发,将字符串可能出现的情况全部都列出来,然后在字符串中查找是否出现相应的字符串来判断相应的值。如全部可能的情况如下:
{"0","I","II","III","IV","V","VI","VII","VIII","IX"},
{"0","X","XX","XXX","XL","L","LX","LXX","LXXX","XC"},
{"0","C","CC","CCC","CD","D","DC","DCC","DCCC","CM"},
{"0","M","MM","MMM"}
然后又罗马数字如"CDLXXI",先判断"MMM"在该数字中是否出现,然后判断在结果中是否加上该值。由于"MMM"没在该数字中出现,所以不加上该值。同理,发现最先出现的是"CD"就在结果中加上400,然后出现的是"LXX"就加上70,最后出现的是"I"就加上1,得到471。这个过程中唯一需要注意的就是一定要从大值开始查找,如在数字中查找“XX”和“XXX”时,如果从小值查找就会出错(读者可以尝试使用“MXXX”验证)。
思路二:我们发现罗马数字中位于左边的值小于其右边的值时,只需要大值减掉小值即可表示该字符串表示的值,如"XL"表示L-X=50-10=40,并且需要减得情况只有一位,即不会出现“XXL”的情况。当罗马数字中小值位于大值右边时,加上该小值即可,如“LXX”表示L+X+X=50+10+10=70。因此只需遍历一次罗马数字即可,如"CDLXXI",先是“C”,即在结果中加上100,然后再是“D”,因为C<D(100<500),所以这两个字符表示(D-C=500-100=400),因此在结果中加上500,再减200(处理“C”时加上了100,而实际情况这一百应该是被减掉的,因此应该减掉100,再减掉之前加上的100),得到400,再是“L”,直接加上50(D>L)即可,结果得到450,再是“X”,加上10即可(L>X)),得到460,再是“X”加上10(X=X),得到470,最后是“I”,加上1即可(X>I),得到最后的结果,即471。
详细思路可以看代码。
代码
java版
public class Solution
{
public int romanToInt(String s)
{
String[][] c={{"0","I","II","III","IV","V","VI","VII","VIII","IX"},
{"0","X","XX","XXX","XL","L","LX","LXX","LXXX","XC"},
{"0","C","CC","CCC","CD","D","DC","DCC","DCCC","CM"},
{"0","M","MM","MMM"}};
int total=0;
for(int i=3;i>=0;i--)
{
for (int j=c[i].length-1;j>=0;j--)
{
String x=c[i][j];
if(s.contains(x) && s.startsWith(x))
{
total+=j*Math.pow(10,i);
s=s.substring(x.length());
//System.out.println(s);
break;
}
}
}
return total;
}
}
java版本2
public class Solution
{
public int romanToInt(String s)
{
Map<Character,Integer> map=new HashMap<Character,Integer>();
map.put('I',1);
map.put('V',5);
map.put('X',10);
map.put('L',50);
map.put('C',100);
map.put('D',500);
map.put('M',1000);
int total=map.get(s.charAt(s.length()-1));
int pre=total;
for(int i=s.length()-2;i>=0;i--)
{
int cur=map.get(s.charAt(i));
if(cur<pre)
{
total=total-cur;
}
else
{
total=total+cur;
}
pre=cur;
}
return total;
}
}
java版本3
public class Solution
{
public int romanToInt(String s)
{
int nums[]=new int[s.length()];
for(int i=0;i<s.length();i++){
switch (s.charAt(i)){
case 'M':
nums[i]=1000;
break;
case 'D':
nums[i]=500;
break;
case 'C':
nums[i]=100;
break;
case 'L':
nums[i]=50;
break;
case 'X' :
nums[i]=10;
break;
case 'V':
nums[i]=5;
break;
case 'I':
nums[i]=1;
break;
}
}
int sum=0;
for(int i=0;i<nums.length-1;i++){
if(nums[i]<nums[i+1])
sum-=nums[i];
else
sum+=nums[i];
}
return sum+nums[nums.length-1];
}
}
C语言版
int getValue(char c)
{
switch(c)
{
case 'I':
return 1;
case 'V':
return 5;
case 'X':
return 10;
case 'L':
return 50;
case 'C':
return 100;
case 'D':
return 500;
case 'M':
return 1000;
default:
return 0;
}
}
int romanToInt(char* s)
{
int total=getValue(s[0]);
int pre=total;
s++;
while(*s)
{
int cur=getValue(s[0]);
if(pre<cur)
{
total-=2*pre;
total+=cur;
}
else
{
total+=cur;
}
pre=cur;
s++;
}
return total;
}