首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何用以下逻辑在python中为罗马数字到整数转换编写代码

如何用以下逻辑在python中为罗马数字到整数转换编写代码
EN

Stack Overflow用户
提问于 2020-08-14 16:10:41
回答 3查看 243关注 0票数 0

我试图将给定的罗马数字转换为仅用于编程实践的数字,使用以下逻辑(除非错误地考虑到这个逻辑,否则我不想改变这个逻辑),

代码语言:javascript
运行
复制
M - 1000, C-100, X-10, V-5, I-1

例子:

代码语言:javascript
运行
复制
Input - MCMXCVI

Expected Result - 1996

逻辑- 1000 + (1000-100) + (100-10) + 5 + 1

索引- 1 + (3-2) + (5-4) + 6 + 7

在这里,我正在搜索从当前值减去它的下一个值,如果它不是更大,我们通常是在添加它。

这里是我尝试过的,我不能正确地编码它,因为我花了很多时间,想去寻求帮助。

代码语言:javascript
运行
复制
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')

得到的输出是

代码语言:javascript
运行
复制
3185 

我希望能得到

代码语言:javascript
运行
复制
1996
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-08-14 17:46:30

我对您现有的代码做了一些小修改!

在默认情况下,我添加了一个变量“

  1. ”设置为false,当result_less将其设置为true
  2. 以检查我们是否减去时,我使用了此标志,当标志为true时,我使其为False,并跳过一个新的if语句,用于检查result_more上的最后一个数字
  3. ,result+=retvalind,未在result_less上使用result_less值
  4. ,结果+=retvalind+1-retvalind。在这两种情况下,为了简单起见,我都更改了结果值,而不是更改越来越少的值。

我去掉了那些result_more和result_less变量,但是保留了打印语句。

这是您的代码,修改如下:

代码语言:javascript
运行
复制
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')
票数 1
EN

Stack Overflow用户

发布于 2020-08-14 16:28:41

您可以使用(自我实现):

代码语言:javascript
运行
复制
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)
票数 2
EN

Stack Overflow用户

发布于 2020-08-14 16:33:37

你可以改变基本概念。如果你逆转罗马数字,基本上从字符串的右边开始,整件事情就会变得很简单。

其思想是,如果从右开始,如果下一个数字更大或等于当前数字,则将该数字添加到总数中,如果下一个数字小于前一个数字,则从总数中减去该数字。

代码语言:javascript
运行
复制
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
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63416373

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档