簡體   English   中英

Python - 將羅馬數字轉換為 integer

[英]Python - Convert a roman numeral to an integer

我嘗試了以下Python 3代碼,這些代碼從羅馬轉換為 Integer。

代碼一目了然。 但是當我輸入XV或與XV值相關時,會發生某些問題。

例如:當我嘗試V時,代碼不起作用,但IV顯示正確的值。

我的代碼:

class Solution(object):
   def romanToInt(self, s):
      """
      :type s: str
      :rtype: int
      """
      roman = {'I':1,'V':5,'X':10,'L':50,'C':100,'D':500,'M':1000,'IV':4,'IX':9,'XL':40,'XC':90,'CD':400,'CM':900}
      i = 0
      num = 0
      while i < len(s):
         if i+1<len(s) and s[i:i+2] in roman:
            num+=roman[s[i:i+2]]
            i+=2
         else:
            #print(i)
            num+=roman[s[i]]
            i+=1
      return num
ob1 = Solution()

message = str(input("Please enter your roman number: "))
if message <= ("MMMCMXCIX"):
   print (ob1.romanToInt(message))
else:
    print ("Try again")

我設置的條件是,如果輸入的羅馬數字等於或小於MMMCMXCIX ,它將打印羅馬數字; 否則它將打印Try again

問題是當我輸入XV或與XV值相關時,output 顯示Try again

請幫助我了解我哪里出錯了。

那是因為您正在比較字符串而不是首先將羅馬轉換為 int 而不是檢查

class Solution(object):
   def romanToInt(self, s):
      """
      :type s: str
      :rtype: int
      """
      roman = {'I':1,'V':5,'X':10,'L':50,'C':100,'D':500,'M':1000,'IV':4,'IX':9,'XL':40,'XC':90,'CD':400,'CM':900}
      i = 0
      num = 0
      while i < len(s):
         if i+1<len(s) and s[i:i+2] in roman:
            num+=roman[s[i:i+2]]
            i+=2
         else:
            #print(i)
            num+=roman[s[i]]
            i+=1
      return num
ob1 = Solution()

message = str(input("Please enter your roman number: "))
# converting to integer than comparing the value of "MMMCMXCIX"
if ob1.romanToInt(message) <= 8999:
   print (ob1.romanToInt(message))
else:
    print ("Try again")

最后它只是一個數字的加法,你只需要弄清楚它們是否需要被解釋為正數或負數:

roman = {'I':1,'V':5,'X':10,'L':50,'C':100,'D':500,'M':1000,'IV':4,'IX':9,'XL':40,'XC':90,'CD':400,'CM':900}

def roman2Dec(inp):
    inpNum = [roman[x] for x in inp]
    return sum([-x if i < len(inpNum)-1 and x < inpNum[i+1] else x for i, x in enumerate(inpNum)])

for nums in [('IX', 9), ('XL', 40), ('LXI', 61), ('MMMCMXCIX', 3999)]:
    result = roman2Dec(nums[0])
    print result == nums[1]

Output:

True
True
True
True

如評論中所述,問題是由於您比較字符串而不是先轉換為 int 然后進行比較而引起的。

您可以嘗試的其他方法是:

def romanToInt(s):
  d = {'m': 1000, 'd': 500, 'c': 100, 'l': 50, 'x': 10, 'v': 5, 'i': 1}
  n = [d[i] for i in s.lower() if i in d]
  return sum([i if i>=n[min(j+1, len(n)-1)] else -i for j,i in enumerate(n)])

print(romanToInt('X')) # 10
print(romanToInt('V')) # 5
print(romanToInt('IV')) # 4
print(romanToInt('XV')) # 15

在我看來,兩者都更像pythonic。

下面列出了一些方法及其各自的運行時將羅馬數字轉換為整數。

解決方案 1:(大約運行時間 = 52 毫秒)

def romanToInt(self, s: str) -> int:
 s = s.upper()
 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:
 s = s.upper()
 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:
 s = s.upper()
 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

最簡單的解決方案有時似乎是最好的:)

您可以通過以下簡單方式解決此問題。

這個問題可以通過這樣的想法來解決

在下面,上述特殊情況由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
def romanToInt(s):    
    p=z=0
    for i in map('IVXLCDM'.find,s[::-1]):x=[1,5][i%2]*10**(i//2);z+=[x,-x][p>x];p=x
    return z

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM