用 python 对皇家国王名字进行排序
Sort Royal King names with python
您好,我正在尝试解决这个问题,但我无法解决这些错误
我想如何解决这个问题的想法是首先将名称拆分为名称和罗马数字,然后将罗马数字转换为阿拉伯数字,然后像整数一样排序,然后将阿拉伯数字反向转换为罗马数字
def from_roman(num):
roman_numerals = {'I':1, 'V':5, 'X':10, 'L':50, 'C':100, 'D':500, 'M':1000}
result = 0
for i,c in enumerate(num):
if (i+1) == len(num) or roman_numerals[c] >= roman_numerals[num[i+1]]:
result += roman_numerals[c]
else:
result -= roman_numerals[c]
return result
# convert from arabic to roman
def to_roman(num):
roman_numerals = {1:'I', 5:'V', 10:'X', 50:'L', 100:'C', 500:'D', 1000:'M'}
result=''
for i,c in enumerate(num):
if (i+1) == len(num) or roman_numerals[c] >= roman_numerals[num[i+1]]:
result += roman_numerals[c]
else:
result -= roman_numerals[c]
return result
def SortPrintKingsNames(kings):
romanList=[]
arabicList=[]
#sort kings name first
kings.sort()
#sort roman numbers by converting them to arabic and sorting them
for king in kings:
romanList.append(from_roman(king.split()[-1]))
romanList.sort()
#convert to roman again
for roman in romanList:
arabicList=to_roman(roman)
for k in kings:
# print names with roman number
print(k,arabicList[k])
错误如下:
Traceback (most recent call last):
File "Solution.py", line 58, in <module>
SortPrintKingsNames(kingsNames)
File "Solution.py", line 48, in SortPrintKingsNames
arabicList=to_roman(roman)
File "Solution.py", line 29, in to_roman
for i,c in enumerate(num):
TypeError: 'int' object is not iterable
出现此错误是因为您正在尝试枚举阿拉伯(整数)值。
更新 to_roman
功能以解决问题。
试试这个代码:
def from_roman(num): # IV > 4
roman_numerals = {'I':1, 'V':5, 'X':10, 'L':50, 'C':100, 'D':500, 'M':1000}
result = 0
for i,c in enumerate(num):
if (i+1) == len(num) or roman_numerals[c] >= roman_numerals[num[i+1]]:
result += roman_numerals[c]
else:
result -= roman_numerals[c]
return result
# convert from arabic to roman
def to_roman(num): # 4 > IV
roman_numerals = {1:'I', 5:'V', 10:'X', 50:'L', 100:'C', 500:'D', 1000:'M'}
result=''
for k in list(roman_numerals.keys())[::-1]:
while num >= k:
result+=roman_numerals[k]
num -= k
# do replacements based on 'max 3' rule
rt = [('DCCCC','CM'), ('CCCC','CD'), ('LXXXX','XC'), ('XXXX','XL'), ('VIIII','IX'), ('IIII','IV')]
for r in rt:
result = result.replace(*r) # convert tuple to args
# for i,c in enumerate(num):
# if (i+1) == len(num) or roman_numerals[c] >= roman_numerals[num[i+1]]:
# result += roman_numerals[c]
# else:
# result -= roman_numerals[c]
return result
def SortPrintKingsNames(kings):
print(kings)
romanList=[]
arabicList=[]
#sort kings name first
#kings.sort()
#sort roman numbers by converting them to arabic and sorting them
#romanlist = from_roman(kings)
for king in kings:
romanList.append(from_roman(king.split()[-1]))
print(romanList)
romanList.sort()
print(romanList)
#convert to roman again
for roman in romanList:
arabicList.append(to_roman(roman))
print(arabicList)
# for k in kings:
# print names with roman number
# print(k,arabicList[k])
k = SortPrintKingsNames(['VI','I','IC','XX'])
输出
['VI', 'I', 'IC', 'XX']
[6, 1, 99, 20]
[1, 6, 20, 99]
['I', 'VI', 'XX', 'XCIX']
请注意,IC (99) 不是有效的罗马数字,因此将其转换为 XCIX。
替换是根据 'max 3' 规则完成的。任何数字只需要 6 个替换,因此列出替换比使用复杂的循环更清晰。
罗马数字规则(注意规则#4):
https://classace.io/learn/math/3rdgrade/roman-numerals-ivxlcdm
附带说明一下,如果这用于注册号码,则您需要的最大号码是 72 (LXXII)。
https://en.wikipedia.org/wiki/Heinrich_LXXII,_Prince_Reuss_of_Lobenstein_and_Ebersdorf
def roman_to_int(s:str):
rom_to_int_map = {"I": 1, "V": 5, "X": 10, "L": 50, "C": 100, "D": 500, "M": 1000}
sub_map = {'IV': 4, 'IX':9, 'XL': 40, 'XC': 90, 'CD':400, 'CM': 900}
summation = 0
idx = 0
while idx < len(s):
if s[idx:idx+2] in sub_map:
summation += sub_map.get(s[idx:idx+2])
idx += 2
else:
summation += rom_to_int_map.get(s[idx])
idx += 1
return summation
def sort_roman(names):
name_array = []
for name in names:
n, num = name.split()
num = roman_to_int(num)
name_array.append((n, num, name))
name_array.sort(key=lambda x: [x[0], x[1]])
return list(map(lambda x:x[2], name_array))
sort_roman["Louis IV", "Louis I"]
// Result: ["Louis I", "Louis IV"]
您好,我正在尝试解决这个问题,但我无法解决这些错误
我想如何解决这个问题的想法是首先将名称拆分为名称和罗马数字,然后将罗马数字转换为阿拉伯数字,然后像整数一样排序,然后将阿拉伯数字反向转换为罗马数字
def from_roman(num):
roman_numerals = {'I':1, 'V':5, 'X':10, 'L':50, 'C':100, 'D':500, 'M':1000}
result = 0
for i,c in enumerate(num):
if (i+1) == len(num) or roman_numerals[c] >= roman_numerals[num[i+1]]:
result += roman_numerals[c]
else:
result -= roman_numerals[c]
return result
# convert from arabic to roman
def to_roman(num):
roman_numerals = {1:'I', 5:'V', 10:'X', 50:'L', 100:'C', 500:'D', 1000:'M'}
result=''
for i,c in enumerate(num):
if (i+1) == len(num) or roman_numerals[c] >= roman_numerals[num[i+1]]:
result += roman_numerals[c]
else:
result -= roman_numerals[c]
return result
def SortPrintKingsNames(kings):
romanList=[]
arabicList=[]
#sort kings name first
kings.sort()
#sort roman numbers by converting them to arabic and sorting them
for king in kings:
romanList.append(from_roman(king.split()[-1]))
romanList.sort()
#convert to roman again
for roman in romanList:
arabicList=to_roman(roman)
for k in kings:
# print names with roman number
print(k,arabicList[k])
错误如下:
Traceback (most recent call last):
File "Solution.py", line 58, in <module>
SortPrintKingsNames(kingsNames)
File "Solution.py", line 48, in SortPrintKingsNames
arabicList=to_roman(roman)
File "Solution.py", line 29, in to_roman
for i,c in enumerate(num):
TypeError: 'int' object is not iterable
出现此错误是因为您正在尝试枚举阿拉伯(整数)值。
更新 to_roman
功能以解决问题。
试试这个代码:
def from_roman(num): # IV > 4
roman_numerals = {'I':1, 'V':5, 'X':10, 'L':50, 'C':100, 'D':500, 'M':1000}
result = 0
for i,c in enumerate(num):
if (i+1) == len(num) or roman_numerals[c] >= roman_numerals[num[i+1]]:
result += roman_numerals[c]
else:
result -= roman_numerals[c]
return result
# convert from arabic to roman
def to_roman(num): # 4 > IV
roman_numerals = {1:'I', 5:'V', 10:'X', 50:'L', 100:'C', 500:'D', 1000:'M'}
result=''
for k in list(roman_numerals.keys())[::-1]:
while num >= k:
result+=roman_numerals[k]
num -= k
# do replacements based on 'max 3' rule
rt = [('DCCCC','CM'), ('CCCC','CD'), ('LXXXX','XC'), ('XXXX','XL'), ('VIIII','IX'), ('IIII','IV')]
for r in rt:
result = result.replace(*r) # convert tuple to args
# for i,c in enumerate(num):
# if (i+1) == len(num) or roman_numerals[c] >= roman_numerals[num[i+1]]:
# result += roman_numerals[c]
# else:
# result -= roman_numerals[c]
return result
def SortPrintKingsNames(kings):
print(kings)
romanList=[]
arabicList=[]
#sort kings name first
#kings.sort()
#sort roman numbers by converting them to arabic and sorting them
#romanlist = from_roman(kings)
for king in kings:
romanList.append(from_roman(king.split()[-1]))
print(romanList)
romanList.sort()
print(romanList)
#convert to roman again
for roman in romanList:
arabicList.append(to_roman(roman))
print(arabicList)
# for k in kings:
# print names with roman number
# print(k,arabicList[k])
k = SortPrintKingsNames(['VI','I','IC','XX'])
输出
['VI', 'I', 'IC', 'XX']
[6, 1, 99, 20]
[1, 6, 20, 99]
['I', 'VI', 'XX', 'XCIX']
请注意,IC (99) 不是有效的罗马数字,因此将其转换为 XCIX。
替换是根据 'max 3' 规则完成的。任何数字只需要 6 个替换,因此列出替换比使用复杂的循环更清晰。
罗马数字规则(注意规则#4):
https://classace.io/learn/math/3rdgrade/roman-numerals-ivxlcdm
附带说明一下,如果这用于注册号码,则您需要的最大号码是 72 (LXXII)。
https://en.wikipedia.org/wiki/Heinrich_LXXII,_Prince_Reuss_of_Lobenstein_and_Ebersdorf
def roman_to_int(s:str):
rom_to_int_map = {"I": 1, "V": 5, "X": 10, "L": 50, "C": 100, "D": 500, "M": 1000}
sub_map = {'IV': 4, 'IX':9, 'XL': 40, 'XC': 90, 'CD':400, 'CM': 900}
summation = 0
idx = 0
while idx < len(s):
if s[idx:idx+2] in sub_map:
summation += sub_map.get(s[idx:idx+2])
idx += 2
else:
summation += rom_to_int_map.get(s[idx])
idx += 1
return summation
def sort_roman(names):
name_array = []
for name in names:
n, num = name.split()
num = roman_to_int(num)
name_array.append((n, num, name))
name_array.sort(key=lambda x: [x[0], x[1]])
return list(map(lambda x:x[2], name_array))
sort_roman["Louis IV", "Louis I"]
// Result: ["Louis I", "Louis IV"]