侧边栏壁纸
博主头像
小鱼吃猫博客博主等级

你所热爱的,便是你的生活。

  • 累计撰写 113 篇文章
  • 累计创建 47 个标签
  • 累计收到 9 条评论

目 录CONTENT

文章目录

整数与罗马数字之间的转换

小鱼吃猫
2023-08-24 / 1 评论 / 4 点赞 / 51 阅读 / 4692 字

转换规则

题目来源于Leetcode,整数与罗马数字之间的转换规则大致如下:

字符 数值 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。
  • 这里只是为了方便理解,把他分成了两个对象,实际操作中,可以合并成一个。

代码实现

  1. 罗马数字->整数
  • 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;
}
  1. 整数->罗马数字
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();
}
4

评论区