该算法题来自于leetcode Q13,题目要求将罗马数字转成10进制的阿拉伯数字。
一、背景知识:罗马数字表示方法
罗马数字采用如下7个字符组合来表示一个整数:
Symbol | Value |
---|---|
I | 1 |
V | 5 |
X | 10 |
L | 50 |
C | 100 |
D | 500 |
M | 1000 |
其中4和9分别采用5-1和10-1的形式代替,比如:
1949可以表示为:MCMXLIX,这是因为1949=1000+900+40+9, 具体如下表所示:
Symbol | Value |
---|---|
M | 1000 |
CM | 900 |
XL | 40 |
IX | 9 |
二、题目:给定一个罗马数字,输出对应的数字
Given a roman numeral, convert it to an integer. Input is guaranteed to be within the range from 1 to 3999.
给定一个罗马数字(由上述7个字符中的若干组成),将其转换为10进制整数,输入的大小限定为[1, 3999]范围内。
三、思路分析
- 遍历给定的罗马数字(一个字符串),该字符串可以拆分成若干个部分,每部分都由1或者2个字符组成,其中2个字符的必定是属于4或者9的情况;
- 累加各部分对应的10进制整数,2个字符对应的整数等于后者减去前者,比如CM对应的为1000-100=900。
四、代码
java代码
import java.util.HashMap;
import java.util.Map;
public class Roman2Int {
public int roman2Int(String originalStr){
int sum = 0;
Map<Character, Integer> map = new HashMap<>();
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);
if(originalStr.length() == 1){
return map.get(originalStr.charAt(0));
}
// 遍历每个char,比较相邻两个char,如果former < latter,说明两个char组合联合代表一个整数值
for(int i=0; i<originalStr.length()-1; i++) {
int former = map.get(originalStr.charAt(i));
int latter = map.get(originalStr.charAt(i + 1));
if (former >= latter) {
// 最后一个char会被忽略
sum += former;
} else {
sum += latter - former;
i++;
}
}
// 加上最后一个char
boolean addLastChar = map.get(originalStr.charAt(originalStr.length()-2))
>= map.get(originalStr.charAt(originalStr.length()-1));
if(addLastChar){
sum += map.get(originalStr.charAt(originalStr.length()-1));
}
return sum;
}
public class Main {
public static void main(String[] args){
System.out.println(new Roman2Int().roman2Int("MCMXLIX"));
}
}
python代码
def roman2Int(originalStr):
sum = 0
length = len(originalStr)
map = {'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000}
if len(originalStr) == 1:
return map.get(originalStr[0])
i = 0
while i < length - 1:
former = map.get(originalStr[i])
latter = map.get(originalStr[i+1])
if former >= latter:
sum += former
i += 1
else:
sum += latter - former
i += 2
addLastChar = map.get(originalStr[length-2]) >= map.get(originalStr[length-1])
if addLastChar:
sum += map.get(originalStr[length-1])
return sum
print(roman2Int("MCMXCIV"))