0
0
PythonProgramBeginner · 2 min read

Python Program to Convert Roman Numerals to Integer

You can convert Roman numerals to integers in Python by mapping each symbol to its value and adding or subtracting based on the order, for example: roman_to_int = lambda s: sum(-v if i+1 where roman_map is a dictionary of Roman symbols to values.
📋

Examples

InputIII
Output3
InputIX
Output9
InputMCMXCIV
Output1994
🧠

How to Think About It

To convert Roman numerals to integers, look at each symbol from left to right. If a symbol is smaller than the one after it, subtract its value; otherwise, add it. This way, you handle cases like IV (4) where I is less than V, so you subtract I from V.
📐

Algorithm

1
Create a dictionary mapping Roman symbols to their integer values.
2
Initialize a result variable to 0.
3
Loop through each character in the Roman numeral string except the last one.
4
If the current symbol's value is less than the next symbol's value, subtract it from the result.
5
Otherwise, add it to the result.
6
Add the value of the last symbol to the result and return it.
💻

Code

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

print(roman_to_int('III'))
print(roman_to_int('IX'))
print(roman_to_int('MCMXCIV'))
Output
3 9 1994
🔍

Dry Run

Let's trace 'MCMXCIV' through the code

1

Initialize

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

2

Check M and C

M=1000, C=100; 1000 > 100 so add 1000; result=1000

3

Check C and M

C=100, M=1000; 100 < 1000 so subtract 100; result=900

4

Check M and X

M=1000, X=10; 1000 > 10 so add 1000; result=1900

5

Check X and C

X=10, C=100; 10 < 100 so subtract 10; result=1890

6

Check C and I

C=100, I=1; 100 > 1 so add 100; result=1990

7

Check I and V

I=1, V=5; 1 < 5 so subtract 1; result=1989

8

Add last symbol V

Add V=5; result=1994

IndexCurrent SymbolNext SymbolActionResult
0M(1000)C(100)Add 10001000
1C(100)M(1000)Subtract 100900
2M(1000)X(10)Add 10001900
3X(10)C(100)Subtract 101890
4C(100)I(1)Add 1001990
5I(1)V(5)Subtract 11989
6V(5)-Add 51994
💡

Why This Works

Step 1: Mapping Roman Symbols

Each Roman numeral symbol is linked to a fixed integer value using a dictionary for quick lookup.

Step 2: Comparing Adjacent Symbols

By comparing each symbol with the next, the code decides whether to add or subtract the current value.

Step 3: Handling Subtraction Cases

If a smaller value precedes a larger one, it subtracts the smaller to handle numerals like IV or IX correctly.

Step 4: Adding the Last Symbol

The last symbol's value is always added because it has no next symbol to compare.

🔄

Alternative Approaches

Using Regular Expressions to Parse
python
import re

def roman_to_int_regex(s):
    roman_map = {'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000}
    pattern = r'M{0,3}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})'
    if not re.fullmatch(pattern, s):
        return 0
    total = 0
    i = 0
    while i < len(s):
        if i+1 < len(s) and roman_map[s[i]] < roman_map[s[i+1]]:
            total += roman_map[s[i+1]] - roman_map[s[i]]
            i += 2
        else:
            total += roman_map[s[i]]
            i += 1
    return total

print(roman_to_int_regex('MCMXCIV'))
This method validates the Roman numeral format but is more complex and slower due to regex.
Using a Stack to Process Symbols
python
def roman_to_int_stack(s):
    roman_map = {'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000}
    stack = []
    for char in s:
        while stack and roman_map[stack[-1]] < roman_map[char]:
            val = stack.pop()
            stack.append(char)
            stack.append(val)
            break
        else:
            stack.append(char)
    return sum(roman_map[c] for c in stack)

print(roman_to_int_stack('IX'))
This approach uses a stack but is less straightforward and less efficient.

Complexity: O(n) time, O(1) space

Time Complexity

The program loops through the Roman numeral string once, so it runs in linear time relative to the input length.

Space Complexity

It uses a fixed dictionary and a few variables, so space usage is constant regardless of input size.

Which Approach is Fastest?

The direct comparison method is fastest and simplest; regex adds overhead, and stack-based methods are more complex.

ApproachTimeSpaceBest For
Direct ComparisonO(n)O(1)Simple and fast conversion
Regex ValidationO(n) with overheadO(1)Validating format before conversion
Stack MethodO(n)O(n)Demonstrating stack usage but less efficient
💡
Always compare the current Roman symbol with the next to decide whether to add or subtract its value.
⚠️
Beginners often forget to add the value of the last Roman symbol after the loop.