【每日一题20220825】罗马数字转换工具

:mage: 创建一个 RomanNumerals 类,该类可以将罗马数字与整数值相互转换。它应该遵循以下示例中演示的 API。将为每个帮助程序方法测试多个罗马数字值。

现代罗马数字是通过分别表示每个数字(从最左边的数字开始,并跳过值为零的任何数字)来编写的。在罗马数字中,1990被渲染:1000 = M,900 = CM,90 = XC;导致MCMXC。2008 年写为 2000=MM, 8=VIII;或MMVIII。1666 年按降序使用每个罗马符号:MDCLXVI。

输入范围 :1 <= n < 4000

4应该表示为 IV,而不是作为 IIII

例子

RomanNumerals.to_roman(1000) # should return 'M'
RomanNumerals.from_roman('M') # should return 1000

帮助

罗马 数字
I 1
IV 4
V 5
X 10
L 50
C 100
D 500
M 1000

有两条须注意掌握:

  1. 基本数字 Ⅰ、X 、C 中的任何一个、自身连用构成数目、或者放在大数的右边连用构成数目、都不能超过三个;放在大数的左边只能用一个;

  2. 不能把基本数字 V 、L 、D 中的任何一个作为小数放在大数的左边采用相减的方法构成数目;放在大数的右边采用相加的方式构成数目、只能使用一个;

对照表

个位数举例

Ⅰ-1、Ⅱ-2、Ⅲ-3、Ⅳ-4、Ⅴ-5、Ⅵ-6、Ⅶ-7、Ⅷ-8、Ⅸ-9

十位数举例

Ⅹ-10、Ⅺ-11、Ⅻ-12、XIII-13、XIV-14、XV-15、XVI-16、XVII-17、XVIII-18、XIX-19、XX-20、XXI-21、XXII-22、XXIX-29、XXX-30、XXXIV-34、XXXV-35、XXXIX-39、XL-40、XLV-45、XLIX-49、L-50、LI-51、LV-55、LX-60、LXV-65、LXXX-80、XC-90、XCIII-93、XCV-95、XCVIII-98、XCIX-99

百位数举例

C-100、CC-200、CCC-300、CD-400、CDXC-490、CDXCV-495、CDXCIX-499、D-500、DC-600、DCC-700、DCCC-800、CM-900、CMXCIX-999

千位数举例

M-1000、MC-1100、MCD-1400、MD-1500、MDC-1600、MDCLXVI-1666、MDCCCLXXXVIII-1888、MDCCCXCIX-1899、MCM-1900、MCMLXXVI-1976、MCMLXXXIV-1984、MCMXC-1990、MM-2000、MMMCMXCIX-3999

题目难度:一般
题目来源:https://www.codewars.com/kata/51b66044bce5799a7f000003

class RomanNumerals:

    @classmethod
    def to_roman(cls,val: int) -> str:
        return ''

    @classmethod
    def from_roman(cls,roman_num: str) -> int:
        return 0


assert RomanNumerals.to_roman(1000) == 'M'
assert RomanNumerals.to_roman(4) == 'IV'
assert RomanNumerals.to_roman(1) == 'I'
assert RomanNumerals.to_roman(1990) == 'MCMXC'
assert RomanNumerals.to_roman(2008) == 'MMVIII'
assert RomanNumerals.from_roman('XXI') == 21
assert RomanNumerals.from_roman('I') == 1
assert RomanNumerals.from_roman('IV') == 4
assert RomanNumerals.from_roman('MMVIII') == 2008
assert RomanNumerals.from_roman('MDCLXVI') == 1666
class RomanNumerals:

    @classmethod
    def to_roman(cls,val: 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"]
        res,i = '', 0
        while val > 0:
            while val >= nums[i]:
                res += romans[i]
                val -= nums[i]
            i += 1
        return res

    @classmethod
    def from_roman(cls,roman_num: str) -> int:
        dict_luoma = {'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000}
        a = [y for y in roman_num]
        n = dict_luoma[a[-1]]
        for i in range(len(a) - 1):
            if dict_luoma[a[i + 1]] > dict_luoma[a[i]]:
                n = n - dict_luoma[a[i]]
            elif dict_luoma[a[i + 1]] <= dict_luoma[a[i]]:
                n = n + dict_luoma[a[i]]
        return n
class RomanNumerals:

    @classmethod
    def to_roman(cls, val: int) -> str:
        res_list = []
        num_dict = {'1': 'I', '5': 'V', '10': 'X', '50': 'L', '100': 'C', '500': 'D', '1000': 'M'}
        word_list = [int(str(val)[i] + '0' * (len(str(val)) - i - 1)) for i in range(len(str(val)))]
        for word in range(len(word_list)):
            num = word_list[word] // (10 ** (len(word_list) - word - 1))
            if num < 4:
                res_list.append(num * num_dict[str(10 ** (len(word_list) - word - 1))])
            elif num == 4 or num == 9:
                res_list.append(num_dict[str(10 ** (len(word_list) - word - 1))] + num_dict[
                    str((num + 1) * (10 ** (len(word_list) - word - 1)))])
            else:
                res_list.append(num_dict[str(5 * (10 ** (len(word_list) - word - 1)))] + (num - 5) * num_dict[
                    str(10 ** (len(word_list) - word - 1))])
        return ''.join(res_list)

    @classmethod
    def from_roman(cls, roman_num: str) -> int:
        num_dict = {'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000}
        res = num_dict[roman_num[-1]]
        for i in range(len(roman_num) - 1):
            if num_dict[roman_num[i]] >= num_dict[roman_num[i + 1]]:
                res += num_dict[roman_num[i]]
            elif num_dict[roman_num[i]] < num_dict[roman_num[i + 1]]:
                res -= num_dict[roman_num[i]]
        return res

assert RomanNumerals.to_roman(1000) == 'M'
assert RomanNumerals.to_roman(4) == 'IV'
assert RomanNumerals.to_roman(1) == 'I'
assert RomanNumerals.to_roman(1888) == 'MDCCCLXXXVIII'
assert RomanNumerals.to_roman(1990) == 'MCMXC'
assert RomanNumerals.to_roman(2008) == 'MMVIII'
assert RomanNumerals.from_roman('XXI') == 21
assert RomanNumerals.from_roman('I') == 1
assert RomanNumerals.from_roman('IV') == 4
assert RomanNumerals.from_roman('MMVIII') == 2008
assert RomanNumerals.from_roman('MDCLXVI') == 1666
assert RomanNumerals.from_roman('MDCCCLXXXVIII') == 1888