转换规则
题目来源于Leetcode,整数与罗马数字之间的转换规则大致如下:
- 12.整数转罗马数字
- 13. 罗马数字转整数
罗马数字包含以下七种字符:
I
,V
,X
,L
,C
,D
和M
。
字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000
例如, 罗马数字 2
写做 II
,即为两个并列的 1 。12
写做 XII
,即为 X
+ II
。 27
写做 XXVII
, 即为 XX
+ V
+ II
。
通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII
,而是 IV
。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX
。这个特殊的规则只适用于以下六种情况:
I
可以放在V
(5) 和X
(10) 的左边,来表示 4 和 9。X
可以放在L
(50) 和C
(100) 的左边,来表示 40 和 90。C
可以放在D
(500) 和M
(1000) 的左边,来表示 400 和 900。
示例: 整数:58 罗马数字:"LVIII" 解释: L = 50, V = 5, III = 3.
整数: 1994 罗马数字: "MCMXCIV" 解释: M = 1000, CM = 900, XC = 90, IV = 4.
转换方案
定义这些特殊的数字对应关系如下:
single ={"I":1,"V":5,"X":10,"L":50,"C":100,"D":500,"M":1000}
protype={"IV":4,"IX":9,"XL":40,"XC":90,"CD":400,"CM":900}
- 罗马数字->整数: 从左到右,将罗马数字拆分成一个个的数组,优先选择拆分成上边的protype中的两位数,如果组合不成两位,便拆分成single中的一位。然后根据对应关系,直接计算出答案。
- 整数->罗马数字: 这个就跟钱币找零的方法是一样的(实在是太简单了),按从大到小进制进行整除,然后选择对应关系就OK。
- 这里只是为了方便理解,把他分成了两个对象,实际操作中,可以合并成一个。
代码实现
- 罗马数字->整数
- python
def romanToInt(self, s: str) -> int:
nums = {
"I": 1, "V": 5, "X": 10,
"L": 50, "C": 100, "D": 500, "M": 1000,
"IV": 4, "IX": 9,
"XL": 40, "XC": 90,
"CD": 400, "CM": 900
}
if(len(s)==1):
return nums[s]
total = 0
i = 0
while i < len(s):
if i + 1 < len(s) and s[i:i+2] in nums:
total += nums[s[i:i+2]]
i += 2
else:
total += nums[s[i]]
i += 1
return total
- Java
public int romanToInt(String s) {
Map<String, Integer> nums = new HashMap<>();
nums.put("I", 1);
nums.put("V", 5);
nums.put("X", 10);
nums.put("L", 50);
nums.put("C", 100);
nums.put("D", 500);
nums.put("M", 1000);
nums.put("IV", 4);
nums.put("IX", 9);
nums.put("XL", 40);
nums.put("XC", 90);
nums.put("CD", 400);
nums.put("CM", 900);
char[] sArray = s.toCharArray();
int total = 0;
int i = 0;
while (i < sArray.length) {
if (i + 1 < sArray.length && nums.containsKey(sArray[i] + "" + sArray[i + 1])) {
total += nums.get(sArray[i] + "" + sArray[i + 1]);
i += 2;
} else {
total += nums.get(sArray[i] + "");
i += 1;
}
}
return total;
}
- 整数->罗马数字
def intToRoman(self, num):
od = collections.OrderedDict()
od[1000]= "M"
od[900]= "CM"
od[500]= "D"
od[400]= "CD"
od[100]= "C"
od[90]= "XC"
od[50]= "L"
od[40]= "XL"
od[10]= "X"
od[9]= "IX"
od[5]= "V"
od[4]= "IV"
od[1]= "I"
res=""
for i,v in od.items():
max_num=num//i
print(num,i,max_num)
res+=od[i]*max_num
num -= max_num*i
return res
- Java
public String intToRoman(int num) {
Map<Integer,String> map= new LinkedHashMap<>();
map.put( 1000,"M");
map.put( 900,"CM");
map.put( 500,"D");
map.put( 400,"CD");
map.put( 100,"C");
map.put( 90,"XC");
map.put( 50,"L");
map.put( 40,"XL");
map.put( 10,"X");
map.put( 9,"IX");
map.put( 5,"V");
map.put(4,"IV");
map.put(1,"I");
StringBuffer sb = new StringBuffer();
final int[] arr = {num};
map.forEach((key,value)->{
int max = arr[0]/key;
for(int i =0;i<max;i++){
sb.append(value);
}
arr[0] = arr[0]-max*key;
});
return sb.toString();
}
评论区