Roman Numerals Decoder, C++, Codewars
Problem Statement
Create a function that takes a Roman numeral as its argument and returns its value as a numeric decimal integer. You don't need to validate the form of the Roman numeral.
Modern Roman numerals are written by expressing each decimal digit of the number to be encoded separately, starting with the leftmost digit and skipping any 0s. So 1990 is rendered "MCMXC" (1000 = M, 900 = CM, 90 = XC) and 2008 is rendered "MMVIII" (2000 = MM, 8 = VIII). The Roman numeral for 1666, "MDCLXVI", uses each letter in descending order.
Example
"MM" -> 2000
"MDCLXVI" -> 1666
"M" -> 1000
"CD" -> 400
"XC" -> 90
"XL" -> 40
"I" -> 1
Help
Symbol Value
I 1
V 5
X 10
L 50
C 100
D 500
M 1,000
Solving Process
Immediately, the first thing we realize is that we will have to map each symbol to a numerical value, and make sure the value pairs are properly handled, such as IX, where the previous symbol makes this a pair I = 1, X = 10, 10 - 1 = 9. First things first, to handle the value pairs, I chose to use an unordered map.
unordered_map<char, int> roman_map = {
{'I', 1},
{'V', 5},
{'X', 10},
{'L', 50},
{'C', 100},
{'D', 500},
{'M', 1000}
};
This sets the proper numerical value for any numeral. Next, we declare the variable finalSolution and set it to 0. This is the variable that, as you can infer, will hold our answer.
int finalSolution = 0;
Next, we are going to initialize a for loop to go symbol by symbol in the string we are passed. However, since strings in C++ are iterable, I find it best to think of them as an array. This is a good mental model to have when approaching a problem like this. For example, 'MDCLXVI' can be visualized as so:
"MDCLXVI" → ['M', 'D', 'C', 'L', 'X', 'V', 'I']
Here is the for loop.
for (int i = 0; i < roman.length(); i++) { }
Next is our core logic. We are going to define an if statement to take care of the two cases: Normal Additive, or a Subtractive Pair. Our if statement will test for a subtractive pair, and if it is determined to be one, it will subtract. If it is not one, it will go through the else statement and add as a Normal Additive.
for (int i = 0; i < roman.length(); i++) {
if (roman_map[roman[i]] < (i + 1 < roman.length() ? roman_map[roman[i + 1]] : 0)) {
finalSolution -= roman_map[roman[i]];
} else {
finalSolution += roman_map[roman[i]];
}
}
Now our last step is to simply return our completed finalSolution once the for loop exits.
return finalSolution;
Below is the final solution to "Roman Numerals Decoder" in C++.
Solution
/********************************************
* *
* Title: Roman Numerals Decoder *
* Author: krisyotam *
* Date: 2025-07-20 *
* *
*********************************************/
#include <iostream>
#include <string>
#include <unordered_map>
using namespace std;
int solution(string roman) {
unordered_map<char, int> roman_map = {
{'I', 1},
{'V', 5},
{'X', 10},
{'L', 50},
{'C', 100},
{'D', 500},
{'M', 1000}
};
int finalSolution = 0;
for (int i = 0; i < roman.length(); i++) {
if (roman_map[roman[i]] < (i + 1 < roman.length() ? roman_map[roman[i + 1]] : 0)) {
finalSolution -= roman_map[roman[i]];
} else {
finalSolution += roman_map[roman[i]];
}
}
return finalSolution;
}
Links from this note
Links to this note
Bibliography
@misc{codewars-roman-numerals-decoder}