罗马字到整数python [重复]

pdtvr36n  于 2023-01-14  发布在  Python
关注(0)|答案(5)|浏览(125)
    • 此问题在此处已有答案**:

Does "IndexError: list index out of range" when trying to access the N'th item mean that my list has less than N items?(7个答案)
How can I iterate over overlapping (current, next) pairs of values from a list?(12个答案)
4天前关闭。
我试图用python3解决这个python问题,我的代码看起来像这样。

class Solution:
    def romanToInt(self, s: str) -> int:
        # Define integer value to each roman 
        rom_val = {'I': 1, 'V': 5, 'X': 10, 'L': 50,
                  'C': 100, 'D': 500, 'M': 1000}
        # A list of integer values
        value = list(map(rom_val.get, s))
        # The subtracted new number
        new = 0
        # The converted integer number
        integer = 0
        # List to keep the checked roman
        checked = []
        for i, j in enumerate(value):
            if j > value[i+1] or j == value[i+1]:
                checked.append(j)
            if j < value[i+1]:
                new = value[i+1] - j
                checked.append(new)
        return sum(checked)

但是,我得到IndexError:第一个if语句的list index超出了范围。虽然我知道这是一个很简单的问题,但是有一些东西我不明白。所以我有两个问题:1.当然,为什么我会得到这个索引错误?我怎么修复它?2.我解决这个问题的方法正确吗?
非常感谢。

neskvpey

neskvpey1#

下面是一个不同的方法,5行:

d = {'M':1000, 'D':500, 'C':100, 'L':50, 'X':10, 'V':5, 'I':1}

def romanToInt(self, s):
    res, p = 0, 'I'
    for c in s[::-1]:
        res, p = res - d[c] if d[c] < d[p] else res + d[c], c
    return res

基本上,向后看,把每个字母加到result中,除非一个较小的字母在较大的字母前面,在这种情况下,用减法代替加法。

**注意:**以下不是完整的解决方案,只是对问题中提到的错误的修复。您的算法中有一个主要的bug。

比如MCMXCIV应该是1994,但返回3099。这是因为您将C视为100,将M视为1000,但应该将CM视为900。由于上面有一个解决方案,我将此作为练习留给您。
代码的问题在于,即使到达最后一个索引,也会检查i + 1。您可以如下修复:

def romanToInt(s: str) -> int:
        # Define integer value to each roman 
        rom_val = {'I': 1, 'V': 5, 'X': 10, 'L': 50,
                  'C': 100, 'D': 500, 'M': 1000}
        # A list of integer values
        value = list(map(rom_val.get, s))

        # List to keep the checked roman
        checked = []
        for i, j in enumerate(value):
            if i == len(value) - 1:
                checked.append(j)
            elif j >= value[i+1]:
                checked.append(j)
            elif j < value[i+1]:
                checked.append(value[i+1] - j)

        print(checked)
        return sum(checked)

print(romanToInt("LVIII"))

我也让你的代码更简洁一些,删除了不必要的变量。主要的变化只是检查它是否是value中的最后一个索引。

irtuqstp

irtuqstp2#

我知道这是一个回答后,但我想添加3个解决方案与各自的运行时转换罗马数字的数字。

溶液1:(大约运行时间= 52毫秒)

def romanToInt(self, s: str) -> int:

 roman = {'I':1, 'V':5, 'X':10, 'L':50, 'C':100, 'D':500, 'M':1000 }    
 num = 0

 for i in range(len(s)):

    if i!= len(s)-1 and roman[s[i]] < roman[s[i+1]]:
         num += roman[s[i]]*-1
    else:
         num += roman[s[i]]

  return num

溶液2:(大约运行时间= 60毫秒)

def romanToInt(self, s: str) -> int:

 roman = {'I':1, 'V':5, 'X':10, 'L':50, 'C':100, 'D':500, 'M':1000 }    
 num = 0

 s = s.replace("IV", "IIII").replace("IX", "VIIII")
 s = s.replace("XL", "XXXX").replace("XC", "LXXXX")
 s = s.replace("CD", "CCCC").replace("CM", "DCCCC")

 for x in s:
    num += roman[x]

 return num

溶液3:(大约运行时间= 48毫秒)

def romanToInt(self, s: str) -> int:

 roman = {'I':1, 'V':5, 'X':10, 'L':50, 'C':100, 'D':500, 'M':1000 }    
 num = 0

 for i in range(len(s)-1):
    if roman[s[i]] < roman[s[i+1]]:
        num += roman[s[i]]*-1
        continue

     num += roman[s[i]]

  num +=roman[s[-1]]

  return num

最简单的解决方案有时似乎是最好的:)

ws51t4hk

ws51t4hk3#

这个问题可以用这样的想法来解决,即罗马数字中的每一个罗马数字都是按降序排列的,如果不是这样的话,那么它就是一个特殊的情况,比如“IV”、“IX”、“XL”......。
在下文中,上述特殊情况由if语句处理。

def romanToInt(s):
    mapping  = {
        'I': 1,
        'V': 5,
        'X': 10,
        'L': 50,
        'C': 100,
        'D': 500,
        'M': 1000,
        }
        
    min_ = None
    total = 0
    for c in s:
        val = mapping[c]
        print(val)
        if min_ and val > min_:
            total -= min_*2
        else:
            min_ = val
        total += val
                
    return total
zzoitvuj

zzoitvuj4#

看看这段代码,逻辑很容易理解。

**注意:**其思想是以反向方式逐个字符地遍历罗马数字,如果下一个字符大于或等于前一个字符,则进行加法运算。

def romanToDecimal(self, S): 
    d = {
        'I':1, 'V':5, 'X':10, 'L':50, 'C':100, 'D':500, 'M':1000
    }
    res = 0
    old = 'I'
    
    for i in S[::-1]:
        if d[i] >= d[old]:
            res = res + d[i]
        else:
            res = res - d[i]
        old = i
        
    return res
yjghlzjz

yjghlzjz5#

这里,例如,我传递'II'给你的函数,值变成[1,1],现在使用enumerate,你会得到(1,1)作为i,j在你的第二次迭代中,这是导致索引错误,然后你可以很容易地解决这个问题。

相关问题