Conversion d'entiers en chiffres romains en Java
Les chiffres romains utilisent sept symboles (I, V, X, L, C, D, M) combinés par addition et soustraction pour représenter les nombres de 1 à 3999. Un algorithme glouton en une dizaine de lignes Java suffit pour la conversion.
Le principe
On parcourt les valeurs romaines du plus grand au plus petit, en incluant les formes soustractives (IV = 4, IX = 9, XL = 40, etc.). À chaque étape, on ajoute le symbole autant de fois que la valeur entre dans le nombre restant.
Implémentation complète
public class ChiffresRomains {
private static final int[] VALEURS = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
private static final String[] SYMBOLES = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};
public static String enRomain(int nombre) {
if (nombre < 1 || nombre > 3999) {
throw new IllegalArgumentException("Les chiffres romains classiques vont de 1 Ă 3999");
}
StringBuilder sortie = new StringBuilder();
for (int i = 0; i < VALEURS.length; i++) {
while (nombre >= VALEURS[i]) {
sortie.append(SYMBOLES[i]);
nombre -= VALEURS[i];
}
}
return sortie.toString();
}
public static void main(String[] args) {
for (int n : new int[]{1, 4, 9, 14, 49, 99, 500, 1999, 2026, 3999}) {
System.out.printf("%4d = %s%n", n, enRomain(n));
}
}
}
Résultat :
1 = I
4 = IV
9 = IX
14 = XIV
49 = XLIX
99 = XCIX
500 = D
1999 = MCMXCIX
2026 = MMXXVI
3999 = MMMCMXCIX
Conversion inverse — romain → entier
private static final Map<Character, Integer> TABLE = Map.of(
'I', 1, 'V', 5, 'X', 10, 'L', 50, 'C', 100, 'D', 500, 'M', 1000
);
public static int enEntier(String romain) {
int total = 0;
for (int i = 0; i < romain.length(); i++) {
int val = TABLE.get(romain.charAt(i));
int suivant = (i + 1 < romain.length()) ? TABLE.get(romain.charAt(i + 1)) : 0;
if (val < suivant) total -= val;
else total += val;
}
return total;
}
System.out.println(enEntier("MCMXCIX")); // 1999
System.out.println(enEntier("LVI")); // 56
Règles à respecter
- I, X, C, M peuvent se répéter jusqu'à 3 fois (III, XXX).
- V, L, D ne se répètent jamais.
- Formes soustractives autorisées : IV (4), IX (9), XL (40), XC (90), CD (400), CM (900).
- Limite classique : 3999 (MMMCMXCIX).
Pour valider qu'une chaîne est un chiffre romain syntaxiquement correct, utilisez une expression régulière :
String regex = "^M{0,3}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$";
boolean valide = "MCMXCIX".matches(regex); // true
L'algorithme glouton fonctionne parce que les valeurs sont ordonnées : chaque choix localement optimal mène à la solution globale.