整数转罗马数字

题目:罗马数字 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。
给定一个整数,将其转为罗马数字。输入确保在 1 到 3999 的范围内。
来源:https://leetcode-cn.com/problems/integer-to-roman/

法一:自己的代码

思路:第一步先把数字变为字符串并拆分成一个一个的数字,第二步再求出原数字的分解形式,第三步利用字典映射分别求出每个数字对应的字符串,最后再相加

class Solution:
    def intToRoman(self, num: int) -> str:
        def zhuhe(q, dict):
            # 取最高位的数字
            high_num = int([i for i in str(q)][0])
            # 当最高位是0时,乘以一个字符串返回是空
            if high_num < 4:
                return dict['a'] * high_num
            elif high_num == 4:
                return dict['a'] + dict['b']
            elif high_num == 5:
                return dict['b']
            elif high_num == 6:
                return dict['b'] + dict['a']
            elif high_num == 7:
                return dict['b'] + dict['a'] * 2
            elif high_num == 8:
                return dict['b'] + dict['a'] * 3
            elif high_num == 9:
                return dict['a'] + dict['c']
            else:
                return dict['c']
        # 对四种情况分别定义不同的映射字典
        # 注意这里的p表示的是个位十位还是百位
        def dict_map(p,q):
            if p == 0:
                dict = {'a':'I', 'b':'V', 'c':'X'}
            elif p == 1:
                dict = {'a':'X', 'b':'L', 'c':'C'}
            elif p == 2:
                dict = {'a':'C', 'b':'D', 'c':'M'}
            else:
                dict = {'a':'M'}
            return zhuhe(q,dict)
        # 利用for循环把字符串拆分开
        num_list = [i for i in str(num)]
        # 把list中的字符转化为数字
        num_list = list(map(int, num_list))
        # 利用for循环把原数字拆分为几个数字的和
        all_num = []
        for i in range(len(num_list)):
            a = num_list[i] * 10**(len(num_list)-1-i)
            all_num.append(a)
        # 分别对每个数字求其对应的字符串
        # 必须是空,不能赋None
        num_str = ''
        for p,q in enumerate(reversed(all_num)):
            # 注意这里要把字符串加到右边
            num_str = dict_map(p, q) + num_str
        return num_str
if __name__ == '__main__':
    duixiang = Solution()
    ww = duixiang.intToRoman(2005)
    print('结果是:', ww)
View Code

 法二:贪心算法

思路:观察出了2,3,6,7,8数字都是由1,5组合得来的,其组合的原理即贪心算法,先取大的,对于特殊的4,9直接处理

参考:https://leetcode-cn.com/problems/integer-to-roman/solution/tan-xin-suan-fa-by-liweiwei1419/

class Solution:
    def intToRoman(self, num: int) -> str:
        # 把阿拉伯数字与罗马数字可能出现的所有情况和对应关系,放在两个数组中
        # 并且按照阿拉伯数字的大小降序排列,这是贪心选择思想
        nums = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1]
        romans = ["M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"]

        index = 0
        res = ''
        while index < 13:
            # 注意:这里是等于号,表示尽量使用大的"面值"
            while num >= nums[index]:
                res += romans[index]
                num -= nums[index]
            index += 1
        return res
View Code