This is a homework assignment I am having trouble with.
I need to make an integer to Roman Numeral converter using a method. Later, I must then use the program to write out 1 to 3999 in Roman numerals, so hardcoding is out. My code below is very bare-bones; it is a basic I/O loop with a way to exit while using a package for getIntegerFromUser
we made in class.
Is there a way to assign values to Strings and then add them together when I call the method?
Update: I got some pseudo code from my professor to help me, and while I understand what he is trying to say, I am having some trouble with the if
s. Will I be needing many, many if
statements so that my converter will correctly handle the Roman numeral formatting or is there a manner in which I can do this with more efficiency? I've updated my code to reflect my placeholder method.
Update (Oct 28 2012): I got it working. Here's what I ended up using:
public static String IntegerToRomanNumeral(int input) { if (input < 1 || input > 3999) return "Invalid Roman Number Value"; String s = ""; while (input >= 1000) { s += "M"; input -= 1000; } while (input >= 900) { s += "CM"; input -= 900; } while (input >= 500) { s += "D"; input -= 500; } while (input >= 400) { s += "CD"; input -= 400; } while (input >= 100) { s += "C"; input -= 100; } while (input >= 90) { s += "XC"; input -= 90; } while (input >= 50) { s += "L"; input -= 50; } while (input >= 40) { s += "XL"; input -= 40; } while (input >= 10) { s += "X"; input -= 10; } while (input >= 9) { s += "IX"; input -= 9; } while (input >= 5) { s += "V"; input -= 5; } while (input >= 4) { s += "IV"; input -= 4; } while (input >= 1) { s += "I"; input -= 1; } return s; }
One way to approach this is to gradually "move" value from the Arabic numeral to the Roman numeral. Here is the beginning of a routine that will do this, where number is the int that is to be converted: String roman = ""; int N = number; while (N >= 1000) { // Move 1000 from N to roman.
Modern Roman numerals are written by expressing each digit separately, starting with the left most digit and skipping any digit with a value of zero. In Roman numerals: 1990 is rendered: 1000=M, 900=CM, 90=XC; resulting in MCMXC. 2008 is written as 2000=MM, 8=VIII; or MMVIII.
A compact implementation using Java TreeMap and recursion:
import java.util.TreeMap; public class RomanNumber { private final static TreeMap<Integer, String> map = new TreeMap<Integer, String>(); static { map.put(1000, "M"); map.put(900, "CM"); map.put(500, "D"); map.put(400, "CD"); map.put(100, "C"); map.put(90, "XC"); map.put(50, "L"); map.put(40, "XL"); map.put(10, "X"); map.put(9, "IX"); map.put(5, "V"); map.put(4, "IV"); map.put(1, "I"); } public final static String toRoman(int number) { int l = map.floorKey(number); if ( number == l ) { return map.get(number); } return map.get(l) + toRoman(number-l); } }
Testing:
public void testRomanConversion() { for (int i = 1; i<= 100; i++) { System.out.println(i+"\t =\t "+RomanNumber.toRoman(i)); } }
There is actually another way of looking at this problem, not as a number problem, but a Unary problem, starting with the base character of Roman numbers, "I". So we represent the number with just I, and then we replace the characters in ascending value of the roman characters.
public String getRomanNumber(int number) { return join("", nCopies(number, "I")) .replace("IIIII", "V") .replace("IIII", "IV") .replace("VV", "X") .replace("VIV", "IX") .replace("XXXXX", "L") .replace("XXXX", "XL") .replace("LL", "C") .replace("LXL", "XC") .replace("CCCCC", "D") .replace("CCCC", "CD") .replace("DD", "M") .replace("DCD", "CM"); }
I especially like this method of solving this problem rather than using a lot of ifs and while loops, or table lookups. It is also actually a quit intuitive solution when you thinking of the problem not as a number problem.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With