我打算编写一个程序,将罗马数字转换为阿拉伯数字,反之亦然。我已经有一个工作代码,用于转换4000以下的数字。对于大于或等于4000的罗马数字,新的写法是括号表示乘以1000.所以例如4000是(IV),6010是(VI) X等感谢答案。 丹尼尔
编辑:好的,以便解决问题。没有大于3999的罗马数字,所以编写更大数字的方法是在罗马数字周围放置一个条形(或括号),这意味着数字应该乘以1000
现在的功能:
def intToRoman(integer):
rlist = romanList = [(1000, "M"),(900, "CM"),(500, "D"),(400, "CD"),(100, "C"),(90, "XC"),(50, "L"),(40, "XL"),(10, "X"),(9, "IX"),(5, "V"),(4, "IV"),(1, "I")]
romanResult = ""
for wholeNumber in rlist:
while integer >= wholeNumber[0]:
integer -= wholeNumber[0]
romanResult += wholeNumber[1]
return romanResult
def romanToInt(numeral):
rlist = romanList = [(1000, "M"),(900, "CM"),(500, "D"),(400, "CD"),(100, "C"),(90, "XC"),(50, "L"),(40, "XL"),(10, "X"),(9, "IX"),(5, "V"),(4, "IV"),(1, "I")]
index = 0
intResult = 0
for integer, romanNumeral in rlist:
while numeral[index : index + len(romanNumeral)] == romanNumeral:
intResult += integer
index += len(romanNumeral)
答案 0 :(得分:1)
您可以使用divmod()
function同时生成整数除数和余数:
>>> divmod(45, 10)
(4, 5)
这是4次10次,余下5次。
使用该功能,它既产生简单的罗马数字输出,又处理4000的指数的罗马数字变得更加简单。每个较高的指数都包含在增加的括号中:
romanList = [
(1000, "M"), (900, "CM"),
(500, "D"), (400, "CD"),
(100, "C"), (90, "XC"),
(50, "L"), (40, "XL"),
(10, "X"), (9, "IX"),
(5, "V"), (4, "IV"),
(1, "I")
]
def intToRoman(integer):
result = []
parenscount = 0
while integer:
integer, num = divmod(integer, 4000)
romanResult = ""
for value, rchar in romanList:
count, num = divmod(num, value)
romanResult += count * rchar
if romanResult:
result.append('{}{}{}'.format(
'(' * parenscount, romanResult, ')' * parenscount))
parenscount += 1
return ' '.join(result[::-1])
因为我们在result
中按从小到大的顺序添加罗马数字,所以在将字符串连接在一起时,您需要在结尾处反转列表; result[::-1]
使用否定步骤撤消列表。
我将romanList
移动到全局,我们可以在以后将罗马数字解析回数字时重复使用它。
演示:
>>> intToRoman(2013)
'MMXIII'
>>> intToRoman(3999)
'MMMCMXCIX'
>>> intToRoman(4000)
'(I)'
>>> intToRoman(4010230)
'(MII) MMCCXXX'
>>> intToRoman(237310230)
'((XIV)) (MMMCCCXXVII) MMCCXXX'
另一方面,我们可以在每次找到右括号时将结果简化并乘以4000:
def romanToInt(numeral):
result = 0
while numeral:
preparse_length = len(numeral)
groupresult = 0
numeral = numeral.lstrip('( ') # remove opening parens and spaces
for value, rchar in romanList:
while numeral.startswith(rchar):
groupresult += value
numeral = numeral[len(rchar):]
if len(numeral) == preparse_length:
# No valid numerals found, not a Roman numeral then
raise ValueError(
'ValueError: invalid literal for romanToInt: {!r}'.format(numeral))
while numeral[:1] == ')':
groupresult *= 4000
numeral = numeral[1:]
result += groupresult
return result
演示:
>>> romanToInt('MMXIII')
2013
>>> romanToInt('MMMCMXCIX')
3999
>>> romanToInt('(I)')
4000
>>> romanToInt('(MII) MMCCXXX')
4010230
>>> romanToInt('((XIV)) (MMMCCCXXVII) MMCCXXX')
237310230
>>> romanToInt('booh')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 14, in romanToInt
ValueError: ValueError: invalid literal for romanToInt: 'booh'
答案 1 :(得分:0)
您只需要两个功能。一个数字高于4000,一个数字低于数字。
def smallIntToRoman(integer):
rlist = romanList = [(1000, "M"),(900, "CM"),(500, "D"),(400, "CD"),(100, "C"),(90, "XC"),(50, "L"),(40, "XL"),(10, "X"),(9, "IX"),(5, "V"),(4, "IV"),(1, "I")]
romanResult = ""
for wholeNumber in rlist:
while integer >= wholeNumber[0]:
integer -= wholeNumber[0]
romanResult += wholeNumber[1]
return romanResult
def bigIntToRoman(integer):
thousands, rest = divmod(integer, 1000)
return "({}){}".format(smallIntToRoman(thousands), smallIntToRoman(rest))
def intToRoman(integer):
if integer >= 4000:
return bigIntToRoman(integer)
else:
return smallIntToRoman(integer)
def smallRomanToInt(numeral):
rlist = romanList = [(1000, "M"),(900, "CM"),(500, "D"),(400, "CD"),(100, "C"),(90, "XC"),(50, "L"),(40, "XL"),(10, "X"),(9, "IX"),(5, "V"),(4, "IV"),(1, "I")]
if checkIfRomanNumeral(numeral) is False:
pass
elif checkIfRomanNumeral(numeral) is True:
index = 0
intResult = 0
for integer, romanNumeral in rlist:
while numeral[index : index + len(romanNumeral)] == romanNumeral:
intResult += integer
index += len(romanNumeral)
def romainToInt(numeral):
if len(numeral) == 0:
return None
int_parts = numeral[1:].split(')') # Better done with regex
if len(int_parts) == 1:
return smallRomainToInt(numeral)
elif len(int_parts) == 2:
big = smallRomainToInt(int_parts[1])
small = smallRomainToInt(int_parts[0])
if big is None or small is None:
return None
else:
return big * 1000 + small
else:
return None