New feature: Support for converting numbers in a larger range.

To extend the current solution to support even larger ranges of numbers beyond 1,000,000, we can enhance the Roman numeral system to use additional notation for larger values. In Roman numerals, there is no native representation for numbers greater than 1,000,000.
This commit is contained in:
lighting9999 2025-02-10 11:44:48 +08:00 committed by GitHub
parent 338cbafe0d
commit 5de6f728f1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1,61 +1,56 @@
ROMAN = [ ROMAN = [
(1000, "M"), (1000000, "M_"), (900000, "C_M_"), (500000, "D_"), (400000, "C_D_"),
(900, "CM"), (100000, "C_"), (90000, "X_C_"), (50000, "L_"), (40000, "X_L_"),
(500, "D"), (10000, "X_"), (9000, "I_X_"), (5000, "V_"), (4000, "I_V_"),
(400, "CD"), (1000, "M"), (900, "CM"), (500, "D"), (400, "CD"),
(100, "C"), (100, "C"), (90, "XC"), (50, "L"), (40, "XL"),
(90, "XC"), (10, "X"), (9, "IX"), (5, "V"), (4, "IV"), (1, "I")
(50, "L"),
(40, "XL"),
(10, "X"),
(9, "IX"),
(5, "V"),
(4, "IV"),
(1, "I"),
] ]
def roman_to_int(roman: str) -> int: def roman_to_int(roman: str) -> int:
""" """
LeetCode No. 13 Roman to Integer Convert a Roman numeral to an integer, supporting Vinculum notation (underscore _ represents 1000 times).
Given a roman numeral, convert it to an integer. LeetCode No. 13 Roman to Integer
Input is guaranteed to be within the range from 1 to 3999.     Given a roman numeral, convert it to an integer.
https://en.wikipedia.org/wiki/Roman_numerals     Input is guaranteed to be within the range from 1 to 3999.
>>> tests = {"III": 3, "CLIV": 154, "MIX": 1009, "MMD": 2500, "MMMCMXCIX": 3999}     https://en.wikipedia.org/wiki/Roman_numerals
    >>> all(roman_to_int(key) == value for key, value in tests.items())
>>> tests = {"III": 3, "CLIV": 154, "MIX": 1009, "MMD": 2500, "MMMCMXCIX": 3999, "I_V_": 4000, "X_": 10000, "M_": 1000000}
>>> all(roman_to_int(key) == value for key, value in tests.items()) >>> all(roman_to_int(key) == value for key, value in tests.items())
True True
""" """
vals = {"I": 1, "V": 5, "X": 10, "L": 50, "C": 100, "D": 500, "M": 1000} vals = {
total = 0 "I": 1, "V": 5, "X": 10, "L": 50, "C": 100, "D": 500, "M": 1000,
place = 0 "I_": 1000, "V_": 5000, "X_": 10000, "L_": 50000, "C_": 100000, "D_": 500000, "M_": 1000000
while place < len(roman): }
if (place + 1 < len(roman)) and (vals[roman[place]] < vals[roman[place + 1]]): i, total = 0, 0
total += vals[roman[place + 1]] - vals[roman[place]] while i < len(roman):
place += 2 if i + 1 < len(roman) and (roman[i:i+2] in vals): # 处理 `_` 记法
total += vals[roman[i:i+2]]
i += 2
else: else:
total += vals[roman[place]] total += vals[roman[i]]
place += 1 i += 1
return total return total
def int_to_roman(number: int) -> str:
def int_to_roman(number: int) -> str:
""" """
Given a integer, convert it to an roman numeral. Convert an integer to a Roman numeral, supporting Vinculum notation (underscore _ represents 1000 times).
https://en.wikipedia.org/wiki/Roman_numerals  Given a integer, convert it to an roman numeral.
>>> tests = {"III": 3, "CLIV": 154, "MIX": 1009, "MMD": 2500, "MMMCMXCIX": 3999}     https://en.wikipedia.org/wiki/Roman_numerals
>>> tests = {"III": 3, "CLIV": 154, "MIX": 1009, "MMD": 2500, "MMMCMXCIX": 3999, "I_V_": 4000, "X_": 10000, "M_": 1000000}
>>> all(int_to_roman(value) == key for key, value in tests.items()) >>> all(int_to_roman(value) == key for key, value in tests.items())
True True
""" """
if not isinstance(number, int) or number < 1:
raise ValueError("Input must be a positive integer greater than 0")
result = [] result = []
for arabic, roman in ROMAN: for arabic, roman in ROMAN:
(factor, number) = divmod(number, arabic) factor, number = divmod(number, arabic)
result.append(roman * factor) result.append(roman * factor)
if number == 0: if number == 0:
break reak
return "".join(result) return "".join(result)
if __name__ == "__main__": if __name__ == "__main__":
import doctest import doctest
doctest.testmod() doctest.testmod()