/* package whatever; // don't place package name! */
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/* Name of the class has to be "Main" only if the class is public. */
class RomanToDecimalConverter
{
public static void main
(String[] args
) { printRomanToDecimal("XCIX");
printRomanToDecimal("MMMCMXCIX");
//error cases
printRomanToDecimal("IIX");
printRomanToDecimal("IIXX");
printRomanToDecimal("ABC");
printRomanToDecimal("IVX");
}
private static void printRomanToDecimal
(String s
) { int decimal = romanToDecimal(s);
String output
= decimal
!= -1 ? ""+decimal
: "Invalid roman numerals"; System.
out.
println(s
+ ": " + output
); }
public static int romanToDecimal
(String s
) { if (s == null || s.isEmpty() || !s.matches("^(M{0,3})(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$"))
return -1;
final Matcher matcher = Pattern.compile("M|CM|D|CD|C|XC|L|XL|X|IX|V|IV|I").matcher(s);
final int[] decimalValues = {1000,900,500,400,100,90,50,40,10,9,5,4,1};
final String[] romanNumerals
= {"M",
"CM",
"D",
"CD",
"C",
"XC",
"L",
"XL",
"X",
"IX",
"V",
"IV",
"I"}; int result = 0;
while (matcher.find())
for (int i = 0; i < romanNumerals.length; i++)
if (romanNumerals[i].equals(matcher.group(0)))
result += decimalValues[i];
return result;
}
}
LyogcGFja2FnZSB3aGF0ZXZlcjsgLy8gZG9uJ3QgcGxhY2UgcGFja2FnZSBuYW1lISAqLwppbXBvcnQgamF2YS51dGlsLnJlZ2V4Lk1hdGNoZXI7CmltcG9ydCBqYXZhLnV0aWwucmVnZXguUGF0dGVybjsKCi8qIE5hbWUgb2YgdGhlIGNsYXNzIGhhcyB0byBiZSAiTWFpbiIgb25seSBpZiB0aGUgY2xhc3MgaXMgcHVibGljLiAqLwpjbGFzcyBSb21hblRvRGVjaW1hbENvbnZlcnRlcgp7CglwdWJsaWMgc3RhdGljIHZvaWQgbWFpbiAoU3RyaW5nW10gYXJncykgewoJCXByaW50Um9tYW5Ub0RlY2ltYWwoIlhDSVgiKTsKICAgICAgICBwcmludFJvbWFuVG9EZWNpbWFsKCJNTU1DTVhDSVgiKTsKCiAgICAgICAgLy9lcnJvciBjYXNlcwogICAgICAgIHByaW50Um9tYW5Ub0RlY2ltYWwoIklJWCIpOwogICAgICAgIHByaW50Um9tYW5Ub0RlY2ltYWwoIklJWFgiKTsKICAgICAgICBwcmludFJvbWFuVG9EZWNpbWFsKCJBQkMiKTsKICAgICAgICBwcmludFJvbWFuVG9EZWNpbWFsKCJJVlgiKTsKCX0KCQoJcHJpdmF0ZSBzdGF0aWMgdm9pZCBwcmludFJvbWFuVG9EZWNpbWFsKFN0cmluZyBzKSB7CgkJaW50IGRlY2ltYWwgPSByb21hblRvRGVjaW1hbChzKTsKCQlTdHJpbmcgb3V0cHV0ID0gZGVjaW1hbCAhPSAtMSA/ICIiK2RlY2ltYWwgOiAiSW52YWxpZCByb21hbiBudW1lcmFscyI7CgkJU3lzdGVtLm91dC5wcmludGxuKHMgKyAiOiAiICsgb3V0cHV0KTsKCX0KCQoJcHVibGljIHN0YXRpYyBpbnQgcm9tYW5Ub0RlY2ltYWwoU3RyaW5nIHMpIHsKICAgICAgICBpZiAocyA9PSBudWxsIHx8IHMuaXNFbXB0eSgpIHx8ICFzLm1hdGNoZXMoIl4oTXswLDN9KShDTXxDRHxEP0N7MCwzfSkoWEN8WEx8TD9YezAsM30pKElYfElWfFY/SXswLDN9KSQiKSkKICAgICAgICAgICAgcmV0dXJuIC0xOwoKICAgICAgICBmaW5hbCBNYXRjaGVyIG1hdGNoZXIgPSBQYXR0ZXJuLmNvbXBpbGUoIk18Q018RHxDRHxDfFhDfEx8WEx8WHxJWHxWfElWfEkiKS5tYXRjaGVyKHMpOwogICAgICAgIGZpbmFsIGludFtdIGRlY2ltYWxWYWx1ZXMgPSB7MTAwMCw5MDAsNTAwLDQwMCwxMDAsOTAsNTAsNDAsMTAsOSw1LDQsMX07CiAgICAgICAgZmluYWwgU3RyaW5nW10gcm9tYW5OdW1lcmFscyA9IHsiTSIsIkNNIiwiRCIsIkNEIiwiQyIsIlhDIiwiTCIsIlhMIiwiWCIsIklYIiwiViIsIklWIiwiSSJ9OwogICAgICAgIGludCByZXN1bHQgPSAwOwoKICAgICAgICB3aGlsZSAobWF0Y2hlci5maW5kKCkpCiAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcm9tYW5OdW1lcmFscy5sZW5ndGg7IGkrKykKICAgICAgICAgICAgICAgIGlmIChyb21hbk51bWVyYWxzW2ldLmVxdWFscyhtYXRjaGVyLmdyb3VwKDApKSkKICAgICAgICAgICAgICAgICAgICByZXN1bHQgKz0gZGVjaW1hbFZhbHVlc1tpXTsKCiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KfQ==