This question came to my attention from one of my readers a few days ago. They had been asked this question in an online interview and implied that it was quite hard to solve. He had tried converting a Roman Number to Integer, but had ended up in a non-pleasing solution. Well, well, like most readers when I first saw this, I thought to myself… easy! My brain can compute this in half a second so why wouldn’t a computer be able to! As I went on and on in my solution I found out that converting a roman number to integer in java, was not as straight-forward.

I have been insanely busy lately so I will try to be concise and to the point. We need to go through each character of the roman number (assumed to be represented in a String) and add up the values. Easy no? Not exactly… We have forgotten a few points.

We can have numerals that denote negative value. For example in ‘IV’ the ‘I’ denotes -1.

We may have invalid numbers! XLI is valid, but XXLI and XMI are not!

Following this I implemented a small system to keep track of all roman numerals (I, V, X, L, C, D, M) in an array.

You can see that all numerals which start in 5 have an odd index. All that start with 1 have an even index. Keeping in mind that only the numerals that start with 1 can be put in front of bigger numerals to denote negative value (i.e. IX is -1 + 10), we create the below Java code, which as always can be found on GitHub (under the String library).

Converting a roman number to integer – first and last try

/* * @Author: Ajk Palikuqi * * @Question: How To Convert a Roman Number to Integer. * */ package iqLib.stringLib; public class RomanToInteger { public static int ConvertRomanToInteger(String romanNumber) { if ((romanNumber == null) || (romanNumber.length() == 0)) { return -1; } char[] romanNumerals = {'I', 'V', 'X', 'L', 'C', 'D', 'M'}; int lastSeenNumeralIdx = 0; char thisNumeral; int retNumber = 0; int isOddNumeral = 0; for (int i = romanNumber.length() - 1; i >= 0; --i) { for (int j = 0; j < romanNumerals.length; --j) { thisNumeral = romanNumber.charAt(i); if (thisNumeral == romanNumerals[j]) { if ((j % 2) == 1) { isOddNumeral = 1; } else { isOddNumeral = 0; } if (lastSeenNumeralIdx <= j) { retNumber += valueOfNumeral(thisNumeral); } // else if (lastSeenNumeralIdx == j - (1 + isOddNumeral)) { retNumber -= valueOfNumeral(thisNumeral); } else { return -1; } } } } return retNumber; } public static int valueOfNumeral(char romanNumeral) { int retNumber = 1; if ((romanNumeral % 2) == 1) { retNumber *= 5; } return retNumber * powerOfPositive(10, romanNumeral/2); } public static int powerOfPositive(int num, int poweredTo) { int retNumber = 1; for (int i = 0; i < poweredTo; ++i) { retNumber *= num; } return retNumber; } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 /* * @Author: Ajk Palikuqi * * @Question: How To Convert a Roman Number to Integer. * */ package iqLib . stringLib ; public class RomanToInteger { public static int ConvertRomanToInteger ( String romanNumber ) { if ( ( romanNumber == null ) || ( romanNumber . length ( ) == 0 ) ) { return - 1 ; } char [ ] romanNumerals = { 'I' , 'V' , 'X' , 'L' , 'C' , 'D' , 'M' } ; int lastSeenNumeralIdx = 0 ; char thisNumeral ; int retNumber = 0 ; int isOddNumeral = 0 ; for ( int i = romanNumber . length ( ) - 1 ; i >= 0 ; -- i ) { for ( int j = 0 ; j < romanNumerals . length ; -- j ) { thisNumeral = romanNumber . charAt ( i ) ; if ( thisNumeral == romanNumerals [ j ] ) { if ( ( j % 2 ) == 1 ) { isOddNumeral = 1 ; } else { isOddNumeral = 0 ; } if ( lastSeenNumeralIdx <= j ) { retNumber += valueOfNumeral ( thisNumeral ) ; } // else if ( lastSeenNumeralIdx == j - ( 1 + isOddNumeral ) ) { retNumber -= valueOfNumeral ( thisNumeral ) ; } else { return - 1 ; } } } } return retNumber ; } public static int valueOfNumeral ( char romanNumeral ) { int retNumber = 1 ; if ( ( romanNumeral % 2 ) == 1 ) { retNumber * = 5 ; } return retNumber * powerOfPositive ( 10 , romanNumeral / 2 ) ; } public static int powerOfPositive ( int num , int poweredTo ) { int retNumber = 1 ; for ( int i = 0 ; i < poweredTo ; ++ i ) { retNumber * = num ; } return retNumber ; } }

Note that a really good thing about our code is that it’s extensible! If the might Roman Empire came back to power and they decided to continue their numeric system with more characters, our code would be ready to accept them. We would just have to edit our basic char array and we’d be ready to go to translate the Romans with our formidable computer technology which would be able to convert Roman numbers to Integers :)!

As you can see running our roman number to integer – if the code is invalid we return -1, – otherwise we return the converted number.

All things considered as I double check the code I notice that there is a small bug… Can you find it?

As always, hope you guys enjoyed it… and I’ll see you guys next time! ;D