Open In App

Roman to Integer Conversion

Last Updated : 27 Dec, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

Given a string in roman form, the task is to convert this given roman string into an integer.

Roman numerals are based on the symbols I, V, X, L, C, D, and M, which represent 1, 5, 10, 50, 100, 500, and 1,000 respectively. Different arrangements of these symbols represent different numbers. The roman numbers I, II, III, IV, V, VI, VII, VIII, IX, and X represent 1, 2, 3, 4, 5, 6, 7, 8, 9 and 10 respectively.

How does the conversion work?

  • If a smaller value symbol comes before, we subtract. Otherwise, we add.
  • In IV, I comes before V and V has a larger value 5. So our result is 5 - 1 = 4.
  • In VI, V comes before I and I has a smaller value 1. So our result is 5 + 1 = 6.
  • In II, we have same values, so we add and get 1 + 1 = 2
  • In case of more than 2 characters, we traverse from left to right and group only when we see a greater value character after a smaller value character. For example MXVII is 1000 + 10 + 5 + 1 + 1 = 1017. And XLVII is (50 - 10) + 5 + 1 + 1 = 47. Note that L is larger and comes after X.

Examples:

Input: s = "IX"
Output: 9
Explanation: IX is a Roman symbol which represents 10 - 1 = 9

Input: s = "XL"
Output: 40
Explanation: XL is a Roman symbol which represents 50 - 10 = 40

Input: s = "MCMIV"
Output: 1904
Explanation: M is 1000, CM is 1000 - 100 = 900, and IV is 4. So we have total as 1000 + 900 + 4 = 1904

[Expected Approach 1] Using Iterative Comparison - O(n) time and O(1) space

The idea for converting a Roman numeral to an integer is that, we have to traverse the string from left to right. For each symbol compare it with the next symbol (if it exists). If the current symbol is greater than or equal to the next symbol then add its value to the result. Otherwise, subtract its value from the next symbol's value and add the result to the total, and skip the next symbol.

C++
#include <bits/stdc++.h>
using namespace std;

// This function returns value of a Roman symbol
int value(char r) {
    if (r == 'I')
        return 1;
    if (r == 'V')
        return 5;
    if (r == 'X')
        return 10;
    if (r == 'L')
        return 50;
    if (r == 'C')
        return 100;
    if (r == 'D')
        return 500;
    if (r == 'M')
        return 1000;
    return -1;
}

// Returns decimal value of roman numeral
int romanToDecimal(string& s) {
    int res = 0; 

    for (int i = 0; i < s.length(); i++) {
        
        // Get value of current symbol
        int s1 = value(s[i]);

        // Compare with the next symbol if it exists
        if (i + 1 < s.length()) {
            int s2 = value(s[i + 1]);

            // If current value is greater or equal, add it
            // to result
            if (s1 >= s2) {
                res += s1;
            }
            else {
                // Else, add the difference and skip next
                // symbol
                res += (s2 - s1);
                i++;
            }
        }
        else {
            res += s1;
        }
    }

    return res;
}

int main() {
    string s = "IX";
    cout << romanToDecimal(s) << endl;
    return 0;
}
Java
import java.util.*;

class GfG {

    // This function returns value of a Roman symbol
    static int value(char r) {
        if (r == 'I')
            return 1;
        if (r == 'V')
            return 5;
        if (r == 'X')
            return 10;
        if (r == 'L')
            return 50;
        if (r == 'C')
            return 100;
        if (r == 'D')
            return 500;
        if (r == 'M')
            return 1000;
        return -1;
    }

    // Returns decimal value of roman numeral
    static int romanToDecimal(String s) {
        int res = 0; 

        for (int i = 0; i < s.length(); i++) {
            
            // Get value of current symbol
            int s1 = value(s.charAt(i));

            // Compare with the next symbol if it exists
            if (i + 1 < s.length()) {
                int s2 = value(s.charAt(i + 1));

                // If current value is greater or equal, add it
                // to result
                if (s1 >= s2) {
                    res += s1;
                }
                else {
                    // Else, add the difference and skip next
                    // symbol
                    res += (s2 - s1);
                    i++;
                }
            }
            else {
                res += s1;
            }
        }

        return res;
    }

    public static void main(String[] args) {
        String s = "IX";
        System.out.println(romanToDecimal(s));
    }
}
Python
# This function returns value of a Roman symbol
def value(r):
    if r == 'I':
        return 1
    if r == 'V':
        return 5
    if r == 'X':
        return 10
    if r == 'L':
        return 50
    if r == 'C':
        return 100
    if r == 'D':
        return 500
    if r == 'M':
        return 1000
    return -1

# Returns decimal value of roman numeral
def romanToDecimal(s):
	res = 0
	i = 0
	while i < len(s):
        
		# Get value of current symbol
		s1 = value(s[i])

		# Compare with the next symbol if it exists
		if i + 1 < len(s):
			s2 = value(s[i + 1])

			# If current value is greater or equal, 
			# add it to result
			if s1 >= s2:
				res += s1
			else:
				# Else, add the difference and 
				# skip next symbol
				res += (s2 - s1)
				i += 1
		else:
			res += s1
		i += 1

	return res

if __name__ == "__main__":
    s = "IX"
    print(romanToDecimal(s))
C#
using System;

class GfG {
  
    // This function returns value of a Roman symbol
    static int value(char r) {
        if (r == 'I')
            return 1;
        if (r == 'V')
            return 5;
        if (r == 'X')
            return 10;
        if (r == 'L')
            return 50;
        if (r == 'C')
            return 100;
        if (r == 'D')
            return 500;
        if (r == 'M')
            return 1000;
        return -1;
    }

    // Returns decimal value of roman numeral
    static int romanToDecimal(string s) {
        int res = 0; 

        for (int i = 0; i < s.Length; i++) {
          
            // Get value of current symbol
            int s1 = value(s[i]);

            // Compare with the next symbol if it exists
            if (i + 1 < s.Length) {
                int s2 = value(s[i + 1]);

                // If current value is greater or equal, add it
                // to result
                if (s1 >= s2) {
                    res += s1;
                }
                else {
                  
                    // Else, add the difference and skip next
                    // symbol
                    res += (s2 - s1);
                    i++;
                }
            }
            else {
                res += s1;
            }
        }

        return res;
    }

    static void Main() {
        string s = "IX";
        Console.WriteLine(romanToDecimal(s));
    }
}
JavaScript
// This function returns value of a Roman symbol
function value(r) {
    if (r === 'I') 
        return 1;
    if (r === 'V') 
        return 5;
    if (r === 'X') 
        return 10;
    if (r === 'L') 
        return 50;
    if (r === 'C') 
        return 100;
    if (r === 'D') 
        return 500;
    if (r === 'M') 
        return 1000;
    return -1;
}

// Returns decimal value of roman numeral
function romanToDecimal(s) {
    let res = 0; 

    for (let i = 0; i < s.length; i++) {
        
        // Get value of current symbol
        let s1 = value(s[i]);

        // Compare with the next symbol if it exists
        if (i + 1 < s.length) {
            let s2 = value(s[i + 1]);

            // If current value is greater or equal, add it
            // to result
            if (s1 >= s2) {
                res += s1;
            }
            else {
                // Else, add the difference and skip next
                // symbol
                res += (s2 - s1);
                i++;
            }
        }
        else {
            res += s1;
        }
    }

    return res;
}

// Driver Code
let s = "IX"; 
console.log(romanToDecimal(s));

Output
9

Time Complexity: O(n), where n is the length of the string. Only one traversal of the string is required.
Auxiliary Space: O(1), As no extra space is required.

[Expected Approach 2] Using Hashing - O(n) time and O(1) space

We can use an hash map or dictionary to store the values of Roman symbols. And to solve the problem, we have to iterate through the string and for each symbol, check if the current value is less than the next value. If so, subtract the current value from the next value and add the result to the total. Otherwise, add the current value to the total.

C++
#include <bits/stdc++.h>
using namespace std;

int romanToDecimal(string &s) {
    unordered_map<char, int> romanMap = {{'I', 1}, {'V', 5}, 
                                         {'X', 10}, {'L', 50},
                                         {'C', 100}, {'D', 500}, 
                                         {'M', 1000}};

    int res = 0;
    for (int i = 0; i < s.length(); i++) {

        // If the current value is less than the next value, 
        // subtract current from next and add to res
        if (i + 1 < s.length() && romanMap[s[i]] < romanMap[s[i + 1]]) {
            res += romanMap[s[i + 1]] - romanMap[s[i]];

            // Skip the next symbol
            i++;
        }
        else {

            // Otherwise, add the current value to res
            res += romanMap[s[i]];
        }
    }

    return res;
}

int main() {

    string s = "IX";
    cout << romanToDecimal(s) << endl;
    return 0;
}
Java
import java.util.HashMap;

class GfG {

    static int romanToDecimal(String s) {
        HashMap<Character, Integer> romanMap = new HashMap<>();
        romanMap.put('I', 1);
        romanMap.put('V', 5);
        romanMap.put('X', 10);
        romanMap.put('L', 50);
        romanMap.put('C', 100);
        romanMap.put('D', 500);
        romanMap.put('M', 1000);

        int res = 0;
        for (int i = 0; i < s.length(); i++) {

            // If the current value is less than the next value,
            // subtract current from next and add to res
            if (i + 1 < s.length() && romanMap.get(s.charAt(i)) < 
                					romanMap.get(s.charAt(i + 1))) {
                res += romanMap.get(s.charAt(i + 1)) - 
                  					romanMap.get(s.charAt(i));

                // Skip the next symbol
                i++;
            }
            else {

                // Otherwise, add the current value to res
                res += romanMap.get(s.charAt(i));
            }
        }

        return res;
    }

    public static void main(String[] args) {
        String s = "IX";
        System.out.println(romanToDecimal(s));
    }
}
Python
def romanToDecimal(s):
    romanMap = {'I': 1, 'V': 5, 'X': 10, 'L': 50,
                'C': 100, 'D': 500, 'M': 1000}

    res = 0
    i = 0
    while i < len(s):

        # If the current value is less than the next value, 
        # subtract current from next and add to res
        if i + 1 < len(s) and romanMap[s[i]] < romanMap[s[i + 1]]:
            res += romanMap[s[i + 1]] - romanMap[s[i]]

            # Skip the next symbol
            i += 1
        else:

            # Otherwise, add the current value to res
            res += romanMap[s[i]]
        i += 1

    return res

if __name__ == "__main__":
    s = "IX"
    print(romanToDecimal(s))
C#
using System;
using System.Collections.Generic;

class GfG {
    static int romanToDecimal(string s) {
      
        // Create a map to store the Roman numeral values
        Dictionary<char, int> romanMap = new Dictionary<char, int> {
            {'I', 1}, {'V', 5}, {'X', 10}, {'L', 50},
            {'C', 100}, {'D', 500}, {'M', 1000}
        };

        int res = 0;
        for (int i = 0; i < s.Length; i++) {
          
            // If the current value is less than the next value, 
            // subtract current from next and add to res
            if (i + 1 < s.Length && romanMap[s[i]] < romanMap[s[i + 1]]) {
                res += romanMap[s[i + 1]] - romanMap[s[i]];

                // Skip the next symbol
                i++;
            }
            else {
                
                // Otherwise, add the current value to res
                res += romanMap[s[i]];
            }
        }

        return res;
    }

    static void Main() {
        string s = "IX";
        Console.WriteLine(romanToDecimal(s));
    }
}
JavaScript
function romanToDecimal(s) {
    
    // Create a map to store the Roman numeral values
    const romanMap = {
        'I': 1, 'V': 5, 'X': 10, 'L': 50,
        'C': 100, 'D': 500, 'M': 1000
    };

    let res = 0;
    for (let i = 0; i < s.length; i++) {

        // If the current value is less than the next value, 
        // subtract current from next and add to res
        if (i + 1 < s.length && romanMap[s[i]] < romanMap[s[i + 1]]) {
            res += romanMap[s[i + 1]] - romanMap[s[i]];

            // Skip the next symbol
            i++;
        }
        else {

            // Otherwise, add the current value to res
            res += romanMap[s[i]];
        }
    }

    return res;
}

// Main function
let s = "IX";
console.log(romanToDecimal(s));

Output
9

Time Complexity: O(n), where n is the length of the string and we have to iterate the string only once.
Auxiliary Space: O(1), As we are using a map of constant size, so the space complexity becomes O(1).


Next Article
Article Tags :
Practice Tags :

Similar Reads