[英]how to code in python with the following logic for the roman numeral to integer conversion
我正在嘗試將給定的羅馬數字轉換為僅用於編程練習的數字,使用以下邏輯(我不想更改此邏輯,除非它被錯誤地認為)在這里,
M - 1000, C-100, X-10, V-5, I-1
例子:
Input - MCMXCVI
Expected Result - 1996
邏輯 - 1000 + (1000-100) + (100-10) + 5 + 1
索引1 + (3-2) + (5-4) + 6 + 7
在這里,我正在從當前值中搜索下一個值,如果它不大於我們通常添加它,則減去它。
這是我嘗試過的,我無法正確編碼,花了很多時間,想尋求幫助。
def roman_numeral(num):
"""
Write a Python class to convert an roman numeral to a integer.
Logic: https://www.rapidtables.com/convert/number/how-roman-numerals-to-number.html
"""
# Input the string
# Map of roman numerals and the corresponding values in a dictionary.
NUMERALS = {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'}
retval=[]
#Check if each char matches with the dictionary and take the numerical value of the inputed roman
for k in range(len(num)):
for i,j in NUMERALS.items():
if(j==num[k]):
retval.append(i)
elm_count = len(retval)
result=0
result_less=0
result_more=0
ind_tracker=0
#Check if next char from the position of current char if that numerical value is greater then current numerical value.
#If it is greater subtract the current numeric value, if not greater then add it.
for ind,i in enumerate(retval):
print('ind= ',ind,'i= ', i)
#Using this below condition to skip if we have already subtracted the current value from previous value.
if( ind_tracker>ind):
continue
if((ind+1 < elm_count)):
if(i<retval[ind+1]):
#print('result=',result,'retval[ind]=',retval[ind],'retval[ind+1]=', retval[ind+1])
result_less=retval[ind+1]-retval[ind]
print('result_less=',result_less)
ind_tracker=ind+1
else:
result_more+=retval[ind]+result_less
print('result_more=',result_more)
result=result_more
print('final result= ',result)
return result
roman_numeral('MCMXCVI')
我得到的 output 是
3185
我希望得到
1996
您可以使用(自行實現):
class RomanToDecimal:
conversion = {'M': 1000, 'CM': 900, 'D': 500, 'CD': 400, 'C': 100, 'XC': 90, 'L': 50, 'XL': 40, 'X': 10, 'IX': 9,
'V': 5, 'IV': 4, 'I': 1}
def convert(self, roman):
total = 0
while len(roman):
before = len(roman)
for key in self.conversion:
if roman.startswith(key):
total += self.conversion[key]
roman = roman[len(key):]
after = len(roman)
if before == after:
raise ValueError("Not a Roman numeral.")
return total
try:
rtd = RomanToDecimal()
assert rtd.convert('M') == 1000
assert rtd.convert('XXXVI') == 36
assert rtd.convert('MMXII') == 2012
assert rtd.convert('MMXX') == 2020
except ValueError as error:
print(error)
您可以更改基本概念。 如果您反轉羅馬數字並基本上從字符串的右側開始,那么整個事情就會變得非常簡單。
這個想法是,如果您從右側開始,如果下一個數字大於或等於當前數字,則將該數字添加到總數中,如果下一個數字小於前一個數字,則從總數中減去。
roman = "MCMXCVI"
NUMERALS = {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'}
# reverse roman number letters (basically start from the end
roman_reversed = list(reversed(roman))
#invert the dictionary because we want to translate the letter to numbers not the other way around
inverse_NUMERALS = {v: k for k, v in NUMERALS.items()}
# get the number for each character on its own:
lst_numbers = [inverse_NUMERALS.get(x) for x in roman_reversed]
# loop through the list of numbers
total = 0
previous = 0
for numb in lst_numbers:
if numb >= previous:
total += numb
else:
total -= numb
previous = numb
print(total)
#Out[21]: 1996
我對您現有的代碼做了一些小改動!
順便說一句,我擺脫了那些 result_more 和 result_less 變量,但保留了打印語句。
這是您的代碼,已修改:
def roman_numeral(num):
"""
Write a Python class to convert an roman numeral to a integer.
Logic: https://www.rapidtables.com/convert/number/how-roman-numerals-to-number.html
"""
# Input the string
# Map of roman numerals and the corresponding values in a dictionary.
NUMERALS = {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'}
retval=[]
#Check if each char matches with the dictionary and take the numerical value of the inputed roman
for k in range(len(num)):
for i,j in NUMERALS.items():
if(j==num[k]):
retval.append(i)
elm_count = len(retval)
result=0
result_less=0
result_more=0
# ind_tracker=0
flag = False
#Check if next char from the position of current char if that numerical value is greater then current numerical value.
#If it is greater subtract the current numeric value, if not greater then add it.
for ind,i in enumerate(retval):
print('ind= ',ind,'i= ', i)
#Using this below condition to skip if we have already subtracted the current value from previous value.
# if( ind_tracker>ind):
# continue
if(flag):
print("Skipped! Already Subracted!")
flag=False
continue
if((ind+1 == elm_count)):
# if last digit is greater than it's previous, the flag will skip this iteration
print('last digit=',retval[ind])
result+=retval[ind]
if((ind+1 < elm_count)):
if(i<retval[ind+1]):
#print('result=',result,'retval[ind]=',retval[ind],'retval[ind+1]=', retval[ind+1])
# result_less=retval[ind+1]-retval[ind]
result+=retval[ind+1]-retval[ind]
print('result_less=',retval[ind+1]-retval[ind])
# ind_tracker=ind+1
flag = True
else:
# result_more+=retval[ind]+result_less
result+=retval[ind]
print('result_more=',retval[ind])
# result=result_more
print('final result= ',result)
return result
roman_numeral('MCMXCVI')
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.