Python: Roman Numerals to Integers

created at 08-03-2021 views: 5

Roman numerals contain the following seven characters: I, V, X, L, C, D, and M.

charvalue
I1
V5
X10
L50
C100
D500
M1000

For example, the Roman numeral 2 is written as II, which means two parallel ones. 12 is written as XII, which means X+II. 27 is written as XXVII, which is XX+V+II.

Normally, the small number in Roman numerals is to the right of the large number. But there are special cases, for example, 4 is not written as IIII, but IV. The number 1 is to the left of the number 5, and the number represented is equal to the number 4 obtained by subtracting the number 1 from the large number 5. Similarly, the number 9 is represented as IX. This special rule only applies to the following six situations:

I can be placed to the left of V(5) and X(10) to represent 4 and 9.
X can be placed to the left of L(50) and C(100) to represent 40 and 90.
C can be placed to the left of D(500) and M(1000) to represent 400 and 900.
Given a Roman numeral, convert it to an integer. Make sure to enter within the range of 1 to 3999.

from leetcode

Initialization code template:

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

solution

method 1

The first method is to directly convert the Roman numerals in the string to numbers, separated by spaces. Use a space as a separator to divide the string into a list, and then convert each item of the list to an integer and sum:

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

        #Directly convert the Roman numerals in the string to numbers, separated by spaces
        s=s.replace('IV','4 ')
        s=s.replace('IX','9 ')
        s=s.replace('XL','40 ')
        s=s.replace('XC','90 ')
        s=s.replace('CD','400 ')
        s=s.replace('CM','900 ')

        s=s.replace('I','1 ')
        s=s.replace('V','5 ')
        s=s.replace('X','10 ')
        s=s.replace('L','50 ')
        s=s.replace('C','100 ')
        s=s.replace('D','500 ')
        s=s.replace('M','1000 ')

        #Use a space as a separator to split the string into a list
        l = s.split(' ')[:-1]

        #Turn each item of the list into an integer and sum it up
        l = list(map(int, l))

        return sum(l)

method 2

First create a dictionary outside the class, the integers corresponding to the Roman numerals:

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

The method of the class creates a list r internally, and stores the value to be accumulated when traversing the string.

        r = [0]

Next, iterate over the string.

The variable l in the for loop is the last element of r, the newly added element, which is the number represented by the previous character. If the current number is greater than l, it means that the decimal number is before the big number, that is, the special case mentioned in the title has occurred. At this time, the calculation method is to reduce the big number, that is, the current number minus the previous number. At this time, we can turn the previous number into a negative number, so that the subtraction effect can be achieved when accumulating.

for i in s:
             l = r[-1] # variable l is the last element of r
             if d[i]> l: # If the current number is greater than l, it means that there is a special case mentioned in the title
                 r[-1] = -l # Turn the previous number into a negative number
             r.append(d[i]) # Add the current number to the list

Complete code:

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

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

        r = [0]

        for i in s:
            l = r[-1]
            if d[i] > l:
                r[-1] = -l
            r.append(d[i])

        return sum(r)
created at:08-03-2021
edited at: 08-03-2021: