Conversion en chiffres romains

English Version

Ci-dessous, vous trouverez un convertisseur de nombres en chiffres romains, une explication de l'algorithme utilisé et une implémentation en Java.

Convertissez vos nombres

Pour convertir un nombre en chiffres romains, entrez dans la case "Arabe" un nombre entre 1 et 3999 et cliquez sur la flèche vers le bas.
Pour convertir un nombre romain en chiffres arabes, entrez le nombre dans la case "Romain" et cliquez sur la flèche vers le haut

Votre navigateur ne supporte pas Java.
Télécharger Java.

Comment ça marche

Le programme ci-dessus fonctionne selon l'algorithme suivant. Cet algorithme implémente les règles de conversion exposées dans l'article de wikipédia sur les chiffres romains. L'algorithme commence par donner à l'ordinateur la connaissance des chiffres romains unitaires {I, V, X, L, C, D, M} et des combinaisons de chiffres romains suivantes : {IV, IX, XL, XC, CD, CM}. La réunion de ces chiffres unitaires et de ces combinaisons forme une liste de nombres romains élémentaires, dont les valeurs se déclinent comme suit :

Nombres
romains
élémentaires
Valeur
correspondante
M 1000
CM 900
D 500
CD 400
C 100
XC 90
L 50
XL 40
X 10
IX 9
V 5
IV 4
I 1

Conversion Arabe-Romain

Commençons par la conversion des chiffres arabes vers les chiffres romains. Dans ce sens de conversion, l'utilisateur entre un nombre en chiffres entier entre 1 et 3999.

L'algorithme vérifie si le nombre à convertir est plus grand ou égal à la valeur du plus grand nombre romain élémentaire.
Si oui, il concatène au résultat le nombre romain élémentaire et il retire du nombre initial la valeur correspondante.
Si non, il passe à la valeur immédiatement inférieure.
Et ainsi de suite, jusqu'à ce que le reste du nombre initial tombe à zéro :

Reste Résultat
2684 -
1684 M
684 MM
184 MMD
84 MMDC
34 MMDCL
24 MMDCLX
14 MMDCLXX
4 MMDCLXXX
0 MMDCLXXXIV

Conversion Romain-Arabe

Pour la conversion inverse, des chiffres romains vers les chiffres arabes, l'algorithme suit un processus similaire.
Pour commencer, l'algorithme vérifie si le nombre romain à convertir commence par le plus grand nombre romain élémentaire.
Si oui, il ajoute au résultat la valeur correspondante et il augmente la position de vérification de la longueur du nombre romain élémentaire.
Si non, il vérifie avec le nombre romain élémentaire immédiatement inférieur.
Et ainsi de suite, jusqu'à ce que la position de vérification soit la fin du nombre romain initial.

Vérification

Tel que décrit ci-dessus, l'algorithme convertit non seulement les nombres romains valides, mais aussi les nombres romains invalides constitués de nombres romains élémentaires. Par exemple, la conversion de "IIIIIII" en "7" est incorrecte. Il faut donc vérifier que le nombre romain donné à convertir est valide.

Pour vérifier la validité d'un nombre romain, l'algorithme procède de la manière suivante. La conversion d'un nombre arabe en chiffres romains étant bijective, l'algorithme convertit le nombre romain donné en nombre arabe, qu'il reconvertit ensuite en chiffres romains. Si le résultat est identique au nombre romain initial, le nombre est valide. Sinon, il est invalide.

Implémentation en langage Java

L'algorithme ci-dessus peut être implémenté en langage Java de la manière suivante. Dans le morceau de code ci-dessous, les nombres romains élémentaires et leurs équivalents sont indiqués en bleu, les opérations de conversion en rouge et la vérification en vert.

public class RomanNumber {

   private final static String[] BASIC_ROMAN_NUMBERS = { "M", "CM", "D", "CD",
         "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I" };
   private final static int[] BASIC_VALUES = { 1000, 900, 500, 400, 100, 90,
         50, 40, 10, 9, 5, 4, 1 };

   private int value;
   private String romanString;

   public RomanNumber(int value) throws IllegalArgumentException {
      if (1 <= value && value <= 3999) {
         this.value = value;
      } else {
         throw new IllegalArgumentException("" + value);
      }
   

   public RomanNumber(String s) throws IllegalArgumentException {
      String r = s.toUpperCase();
      int index = 0;
      for (int i = 0; i < BASIC_ROMAN_NUMBERS.length; i++) {
         while (r.startsWith(BASIC_ROMAN_NUMBERS[i], index)) {
            this.value += BASIC_VALUES[i];
            index += BASIC_ROMAN_NUMBERS[i].length();
         }
      }

      // Verifies whether the input string is a valid roman number or not.
      RomanNumber tempVerify;
      try {
         tempVerify = new RomanNumber(this.value);
      } catch (IllegalArgumentException e) {
         throw new IllegalRomanNumeralException(s);
      }
      if ((verifyString = tempVerify.toRomanValue()).equals(r)) {
         this.romanString = r;
      } else {
         throw new IllegalRomanNumeralException(s,verifyString);
      }

  }

  public String toRomanValue() {
      if (this.romanString == null) {
         this.romanString = "";
         int remainder = this.value;
         for (int i = 0; i < BASIC_VALUES.length; i++) {
            while (remainder >= BASIC_VALUES[i]) {
               this.romanString += BASIC_ROMAN_NUMBERS[i];
               remainder -= BASIC_VALUES[i];
            }
         }

      }
      return this.romanString;
   }
   
   public int getValue() {
      return this.value;
   }
}

Téléchargez le code source ainsi que le programme de démonstration.

Pour ceux qui préfèrent exécuter le programme de démonstration avec Java Web Start, voici la version JNLP. Si le lien ne fonctionne pas, essayez "Enregistrer la cible du lien sous..."

Add to Google

Remerciements

Merci à Jean-Pierre Norguet pour son aide à la conception de l'algorithme et à la rédaction de cet article.

Questions

Pour toute question relative à l'algorithme, n'hésitez pas à me contacter.

MoxLotus.