package com.mindprod.example;
import static java.lang.System.*;
/**
* convert Roman Numerals to long.
*
* @author Roedy Green, Canadian Mind Products
* @version 1.0 2007-08-17
* @since 2007-08-17
*/
public final class TestRoman
{
/**
* extended roman numeral digits we allow
*/
private static final String VALID_NUMERALS = "IVXLCDMvxlcdm?!";
/**
* values for unit test
*/
private static final String[] TESTS = { "MMVII", "MCMXCIX", "xv", "CIXMCMX" };
/**
* corresponding value of roman numeral digit
*/
private static final long[] CORRESPONDING_VALUES = {
1,
5,
10,
50,
100,
500,
1000,
5000,
10000,
50000,
100000,
500000L,
1000000L,
5000000L,
10000000L };
/**
* Test harness for romanToLong
*
* @param args not used
*/
public static void main( String[] args )
{
for ( String test : TESTS )
{
out.println( test + " : " + romanToLong( test ) );
}
}
/**
* converts a Roman Numeral String to a long. Based on Pascal algorithm posted at
* http://www.merlyn.demon.co.uk/programs/cvt_rome.pas Also accepts fake Roman numbers to extend the range: vxlcdm?!
* v=5000 ... !=10,000,000 This code also accepts numbers that are malformed, in that the numerals are out of order
* e.g. "CIXMCMX"
*
* @param romanNumerals string of roman numerals to convert. No spaces or commas.
*
* @return long equivalent.
*/
@SuppressWarnings( { "WeakerAccess" } )
public static long romanToLong( final String romanNumerals )
{
long sum = 0;
long oldV = 0;
for ( int k = romanNumerals.length() - 1; k >= 0; k-- )
{
final char c = romanNumerals.charAt( k );
final int pos = VALID_NUMERALS.indexOf( c );
if ( pos < 0 )
{
throw new IllegalArgumentException( "invalid Roman numeral "
+ c
+ " in "
+ romanNumerals );
}
long newV = CORRESPONDING_VALUES[ pos ];
if ( newV < oldV )
{
newV = -newV;
}
sum += newV;
oldV = newV;
}
return sum;
}
}