题目:
完全是12题的逆向思维,这题给了个1-3999的罗马数字,要求将它转换成整数。
解析:
我们知道罗马数字就是基于七种符号,例如:II is 2, and XIII is 13. 罗马数字没有0,所以 207是CCVII,1066 is MLXVI.
I = 1
V = 5
X = 10
L = 50
C = 100
D = 500
M = 1000
不难看出,整数化为罗马数字时,是一位一位来转化的,例如:1996:千位是1,为M;百位是9,为CM(1000-100=900);十位为9,为XC;个位为6,为VI;即1996记为罗马数字为:MCMXCVI。
以上一位一位转换的方法适用于将整数转换为罗马数字,那么如何将罗马数字转换为整数呢?
思路:
可以发现,罗马数字转换为整数,只需要考虑将每一位的符号对应的数值相加即可,不过要考虑在罗马数字中“左边小的要减去,左边大的直接加上。”的规则。
做起来也只需要判断一下就好,非常简单。
代码:
class Solution {
public int romanToInt(String s) {
int result = 0;
//罗马数字的七种基本的表示符号和其对应的值,把罗马数字的符号作为获取的key,对应的数值作为value
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);
result = map.get(s.charAt(0));//第一位首先放上
//获得罗马数字,罗马数字遵循左小则减,右小则加
for(int i =1;i<s.length();i++){
//如果右边的数字比较大,要减去左边的数字
if(map.get(s.charAt(i))>map.get(s.charAt(i-1))){
result += map.get(s.charAt(i))-2*map.get(s.charAt(i-1));
}
//如果右边的数字比较小或者相等,则可以直接加上
else{
result += map.get(s.charAt(i));
}
}
return result;
}
}
划重点:
- 用map来存放罗马符号和数值之间的对应关系,通过罗马符号来拿到对应的value值;
- 容易出错的地方:
if(map.get(s.charAt(i))>map.get(s.charAt(i-1))){
result += map.get(s.charAt(i)) - 2*map.get(s.charAt(i-1));
}
这里的被减数倍乘了2,这里可以通过一个过程来分析:
1996--MCMXCVI
0:M result=1000;
1:C 因为C<M,所以result = result +100 =1100;
2:M 因为M>C,所以result = result +1000-2*100 =1900;
....后略....
从扫描到2位上的M时,因为它左边的C比较小,应该做减法然后将结果计入总和才能得到正确值,但是由于前面的C在上一步中已经被加过一次了,所以应该减去它的两倍才能得到正确值!