Surely this has several implementations around, but... someone may still wants to copy-paste this. It only works up to 3999, as after that non-US-ASCII characters are needed. Trivial to extend it for that however... Public Domain:
private static final char[] UPPER_ROMAN_DIGITS = new char[] {
'I', 'V',
'X', 'L',
'C', 'D',
'M'
};
private static final char[] LOWER_ROMAN_DIGITS = new char[] {
'i', 'v',
'x', 'l',
'c', 'd',
'm'
};
/**
* Converts a number to upper-case Roman number, like XVI; up to 3999.
* @throws IllegalArgumentException if the number is not in the [1..3999]
* range.
*/
public static String toUpperRomanNumber(int n) {
return toRomanNumber(n, UPPER_ROMAN_DIGITS);
}
/**
* Converts a number to lower-case Roman number, like xvi; up to 3999.
* @throws IllegalArgumentException if the number is not in the [1..3999]
* range.
*/
public static String toLowerRomanNumber(int n) {
return toRomanNumber(n, LOWER_ROMAN_DIGITS);
}
private static String toRomanNumber(int n, char[] romanDigits) {
// We fetch the decimal digits from right to left.
// The res buffer will contain the Roman number *backwards*, and thus it
// also will contain the Roman "digits" backwards, like 7 will be "IIV".
// At the very end the buffer is reversed.
if (n > 3999) {
throw new IllegalArgumentException("toRomanNumber only supports "
+ "numbers in the [1..3999] range, but the number was "
+ n + ".");
}
StringBuilder res = new StringBuilder();
int base = 0;
while (n != 0) {
int digit = n % 10;
n /= 10;
if (digit != 0) {
switch (digit) {
case 3:
res.append(romanDigits[base]);
// falls through
case 2:
res.append(romanDigits[base]);
// falls through
case 1:
res.append(romanDigits[base]);
break;
case 4:
res.append(romanDigits[base + 1])
.append(romanDigits[base]);
break;
case 8:
res.append(romanDigits[base]);
// falls through
case 7:
res.append(romanDigits[base]);
// falls through
case 6:
res.append(romanDigits[base]);
// falls through
case 5:
res.append(romanDigits[base + 1]);
break;
case 9:
res.append(romanDigits[base + 2]);
res.append(romanDigits[base]);
break;
default:
throw new BugException("Unexpected branch");
}
}
base += 2;
}
return res.reverse().toString();
}
No comments:
Post a Comment