First break the number into its decimal factors like 995 = 900 + 90 + 5 then convert each factor recursively
public class IntegerToRoman {
private Map<Integer, String> romanChars = new HashMap<>();
public IntegerToRoman() {
romanChars.put(1, "I");
romanChars.put(5, "V");
romanChars.put(10, "X");
romanChars.put(50, "L");
romanChars.put(100, "C");
romanChars.put(500, "D");
romanChars.put(1000, "M");
romanChars.put(5000, "V|");
}
public String intToRoman(int num) {
if (num == 0) {
return "";
}
int decimalFact = 0;
StringBuilder result = new StringBuilder();
for (int i = (int)Math.log10(num); i >= 0; i--) {
int divisor = (int) Math.pow(10, i);
decimalFact = num - num % divisor;
result.append(convertDecimalFact(decimalFact));
num = num % divisor;
}
return result.toString();
}
private String convertDecimalFact(int decimalFact){
if(decimalFact == 0){return "";}
int[] keyArray = romanChars.keySet().stream().mapToInt(key -> key)
.sorted().toArray();
for(int i =0 ; i+1<keyArray.length ; i++){
if( keyArray[i] <= decimalFact && decimalFact<= keyArray[i+1] ){
int bigger1stDgt = getLeftMostNum(keyArray[i+1]);
int decimalFact1stDgt = getLeftMostNum(decimalFact);
return decimalFact1stDgt >= bigger1stDgt-1 ?
intToRoman(keyArray[i+1]-decimalFact)+romanChars.get(keyArray[i+1]):
romanChars.get(keyArray[i])+intToRoman(decimalFact - keyArray[i]);
}
}
return "";
}
private int getLeftMostNum(int number) {
int oneDgt = Integer.valueOf(Integer.valueOf(number).toString()
.substring(0, 0 +1));
if(number<10){
return oneDgt;
}
int twoDgts = Integer.valueOf(Integer.valueOf(number).toString()
.substring(0, 0 +2));
return twoDgts==10 ? twoDgts : oneDgt;
}
public static void main(String[] args) {
IntegerToRoman solution = new IntegerToRoman();
System.out.format(" Decimal 3 -> Roman %s \n ", solution.intToRoman(3));
System.out.format("Decimal 4 -> Roman %s \n ", solution.intToRoman(4));
System.out.format("Decimal 8 -> Roman %s \n ", solution.intToRoman(8));
System.out.format("Decimal 58 -> Roman %s \n ", solution.intToRoman(58));
System.out.format("Decimal 344 -> Roman %s \n ", solution.intToRoman(344));
System.out.format("Decimal 995 -> Roman %s \n ", solution.intToRoman(995));
System.out.format("Decimal 1994 -> Roman %s \n ", solution.intToRoman(1994));
}
}
Output is like:
Decimal 3 -> Roman III
Decimal 4 -> Roman IV
Decimal 8 -> Roman VIII
Decimal 58 -> Roman LVIII
Decimal 344 -> Roman CCCXLIV
Decimal 995 -> Roman CMXCV
Decimal 1994 -> Roman MCMXCIV