13. Roman to Integer
题目描述:
Given a roman numeral, convert it to an integer.
Input is guaranteed to be within the range from 1 to 3999.
题目翻译
给出一个罗马数字,将其转换为整数
输入的数据在 1 到 3999 之间
解题方案
标签: String
思路:
- 首先要清楚罗马数字的组成规则。它本质上是由有限的单个字符组成。针对不同的位以及重复次数限制来组成别的数字。它们基本的字符就是如下几个:
I: 1 V: 5 X: 10 L: 50 C: 100 D: 500 M: 1000
所以给定一个罗马数字,无非就是要将一串罗马数字给解析成对应的阿拉伯数字并将结果加起来。这里该如何对给定的罗马数字串解析就是问题的核心。
- 相同的数字连写,所表示的数等于这些数字相加得到的数,例如:III = 3
- 小的数字在大的数字右边,所表示的数等于这些数字相加得到的数,例如:VIII = 8
- 小的数字,限于(I、X和C)在大的数字左边,所表示的数等于大数减去小数所得的数,例如:IV = 4
- 左减数字必须为一位,比如8写成VIII,而非IIX
- 右加数字不可连续超过三位,比如14写成XIV,而非XIIII
- 在一个数的上面画横线,表示这个数扩大1000倍(本题只考虑3999以内的数,所以用不到这条规则)
根据上述规律可知,通过对字符串的遍历,对于出现前面一个数字不小于后面的就直接相加,而否则的情况则要减一个对应的值。而为了描述这个计算,我们可以将单个的罗马数字符和对应的阿拉伯数字映射起来。在具体的实现里可以用一个map来保存。
- 因为遍历过程中,会出现重复累加的情况,所以做减法时要 * 2
代码:
class Solution {
public int romanToInt(String s) {
HashMap<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 value = 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))){
value = value + map.get(s.charAt(i))-2*map.get(s.charAt(i-1));
}
else{
value = value + map.get(s.charAt(i));
}
}
return value;
}
}