简体   繁体   中英

Checking for specific cases for converting roman numeral to integer

I have to create a function with 1 argument that takes a string and converts it into the supposed integer. For example: Input-'IV', Output- 4. If someone could help it'll be appreciated. Also, I'm going to put the code for reference.

def FromRoman(string):
    count = 0
    for i in string:
        if i == 'I':
            count += 1
        elif i == "V":
            count += 5
        elif i == 'X':
            count += 10
        elif i == "L":
            count += 50
        elif i == 'C':
            count += 100
        elif i == 'D':
            count += 500
        elif i == 'M':
            count += 1000
    return count

Assuming the Roman numeral can be more than just the single letter checks that you're doing(Something like LXIX for example), this is how I'd do it.

We would iterate through the roman numeral, and for every 'digit':

  • If the value of the digit is lesser than the value of the next digit in our numeral("IV", value of I is less than value of V), we'd subtract the value of the lower digit from our answer
  • Otherwise we just add the value of the digit.

Here's what I said in code:

def romanToInt(roman):
    valueMap = {'M': 1000,'D': 500 ,'C': 100,'L': 50,'X': 10,'V': 5,'I': 1}
    ans = 0
    for i in range(len(roman) - 1):
        if valueMap[roman[i]] < valueMap[roman[i+1]]:
            ans -= valueMap[roman[i]]
        else:
            ans += valueMap[roman[i]]
    return ans + valueMap[roman[-1]]

Here's an approach without range and len that seems to work:

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


def from_roman(string: str):
    ans = 0
    prev_val = float('inf')

    for c in string:
        val = value_map[c]
        ans += val - 2 * prev_val if val > prev_val else val
        prev_val = val

    return ans

Explanation:

On each iteration, we check if the current numeral is greater than the numeral that came before. For example, given IX then when we are at X , we add 10 to the running total, but we also subtract 2 times the previous value (2 times I in this case).

Testing:

assert from_roman('II') == 2
assert from_roman('IV') == 4
assert from_roman('V') == 5
assert from_roman('XVIII') == 18
assert from_roman('XIX') == 19
assert from_roman('XXVIII') == 28
assert from_roman('XXIX') == 29
assert from_roman('XC') == 90
assert from_roman('CD') == 400
assert from_roman('CM') == 900
assert from_roman('MMXXI') == 2021

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM