// This class provides methods to convert between decimal integers and Roman numerals // Learning Objectives: // 1) problem decomposition // 2) static methods // public class RomanNumerals { //Class Variable: Largest allowable decimal number public static final int MAXIMUM = 5000; //Construct the Roman Numerals equivalent of a given positive integer // Exception thrown if the integer exceeds the defined MAXIMUM value // @param decimal: a positive integer // @return: the Roman Numerals equivalent of the parameter public static String roman(int decimal) { if (decimal <= 0 || decimal > MAXIMUM) throw new RuntimeException("Number out of range 1 .. 5000"); return repeated('M', digit(3, decimal)) + pattern('C', 'D', 'M', digit(2, decimal) ) + pattern('X', 'L', 'C', digit(1, decimal) ) + pattern('I', 'V', 'X', digit(0, decimal) ) ; } //Interpret a Roman Numerals String to get its decimal value // Error checking is limited to recognizing illegal numerals // @param roman: a Roman Numerals string // @return the decimal equivalent of the parameter public static int decimal(String roman) { int lastIndex = roman.length() - 1; int number = numeralValue( roman.charAt(lastIndex) ); for (int i = 0; i < lastIndex; i++) { int one = numeralValue( roman.charAt(i) ); int two = numeralValue( roman.charAt(i + 1) ); if (one < two) number -= one; else number += one; } return number; } //Helper Method // @param numeral: a Roman Numeral - I, V, X, L, C, D, M // @return the decimal value associated with the parameter // Exception thrown is the parameter is invalid private static int numeralValue(char numeral) { switch ( numeral ) { case 'I': return 1; case 'V': return 5; case 'X': return 10; case 'L': return 50; case 'C': return 100; case 'D': return 500; case 'M': return 1000; default : throw new RuntimeException("Invalid Numeral " + numeral); } } //Helper Method // @param symbol: any character // @param count: any non-negative integer // @return the String formed by catenating symbol count times private static String repeated(char symbol, int count) { String image = ""; for ( int k = 1; k <= count; k++ ) image += symbol; return image; } //Helper Method // @param index: the index of a desired digit from a given integer // @param number: an integer from which a digit is to be selected // @return the digit at the given index of the given integer private static int digit(int index, int number) { for ( int i = 1; i <= index; i++ ) number /= 10; return number % 10; } //Helper Method // Compose a Roman-numeral sequence to represent a given single digit // @param i: a one's symbol - I(units) or X(tens) or C(hundreds) // @param v: a five's symbol - V(units) or L(tens) or D(hundreds) // @param x: a ten's symbol - X(units) or C(tens) or M(hundreds) // @param digit: a single-digit integer // @return the Roman Numerals string representing the given digit private static String pattern(char i, char v, char x, int digit) { switch ( digit ) { case 0: return ""; case 1: return "" + i; case 2: return "" + i + i; case 3: return "" + i + i + i; case 4: return "" + i + v; case 5: return "" + v; case 6: return "" + v + i; case 7: return "" + v + i + i; case 8: return "" + v + i + i + i; case 9: return "" + i + x; default: throw new RuntimeException("Single Digit expected"); } } }