Conversion entre les chiffres romains et arabes en Java

1. Introduction

Les anciens Romains ont développé leur propre système numérique appelé chiffres romains. Le système utilise des lettres avec des valeurs différentes pour représenter les nombres. Les chiffres romains sont encore utilisés aujourd'hui dans certaines applications mineures.

Dans ce tutoriel, nous implémenterons des convertisseurs simples qui transformeront les nombres d'un système à l'autre.

2. Chiffres romains

Dans le système romain, nous avons 7 symboles qui représentent des nombres :

  • Je représente 1
  • V représente 5
  • X représente 10
  • L représente 50
  • C représente 100
  • D représente 500
  • M représente 1000

À l'origine, les gens représentaient un 4 avec IIII ou un 40 avec XXXX. Cela peut être assez inconfortable à lire. Il est également facile de confondre quatre symboles l'un à côté de l'autre avec trois symboles.

Les chiffres romains utilisent la notation soustractive pour éviter de telles erreurs. Au lieu de dire quatre fois un (IIII), on peut dire que c'est un de moins que cinq (IV).

En quoi est-ce important de notre point de vue? C'est important car au lieu d'ajouter simplement des nombres symbole par symbole, nous pourrions avoir besoin de vérifier le symbole suivant pour déterminer si le nombre doit être ajouté ou soustrait.

3. Modèle

Définissons une énumération pour représenter les chiffres romains:

enum RomanNumeral { I(1), IV(4), V(5), IX(9), X(10), XL(40), L(50), XC(90), C(100), CD(400), D(500), CM(900), M(1000); private int value; RomanNumeral(int value) { this.value = value; } public int getValue() { return value; } public static List getReverseSortedValues() { return Arrays.stream(values()) .sorted(Comparator.comparing((RomanNumeral e) -> e.value).reversed()) .collect(Collectors.toList()); } }

Notez que nous avons défini des symboles supplémentaires pour aider à la notation soustractive. Nous avons également défini une méthode supplémentaire nommée getReverseSortedValues ​​() .

Cette méthode nous permettra de récupérer explicitement les chiffres romains définis dans l'ordre de valeur décroissant.

4. Du romain à l'arabe

Les chiffres romains ne peuvent représenter que des nombres entiers compris entre 1 et 4000 . Nous pouvons utiliser l'algorithme suivant pour convertir un chiffre romain en nombre arabe (en parcourant les symboles dans l'ordre inverse de M à I ):

LET numeral be the input String representing an Roman Numeral LET symbol be initialy set to RomanNumeral.values()[0] WHILE numeral.length > 0: IF numeral starts with symbol's name: add symbol's value to the result remove the symbol's name from the numeral's beginning ELSE: set symbol to the next symbol

4.1. la mise en oeuvre

Ensuite, nous pouvons implémenter l'algorithme en Java:

public static int romanToArabic(String input) { String romanNumeral = input.toUpperCase(); int result = 0; List romanNumerals = RomanNumeral.getReverseSortedValues(); int i = 0; while ((romanNumeral.length() > 0) && (i  0) { throw new IllegalArgumentException(input + " cannot be converted to a Roman Numeral"); } return result; }

4.2. Tester

Enfin, nous pouvons tester l'implémentation:

@Test public void given2018Roman_WhenConvertingToArabic_ThenReturn2018() { String roman2018 = "MMXVIII"; int result = RomanArabicConverter.romanToArabic(roman2018); assertThat(result).isEqualTo(2018); }

5. De l'arabe vers le romain

Nous pouvons utiliser l'algorithme suivant pour convertir des chiffres arabes en chiffres romains (en parcourant les symboles dans l'ordre inverse de M à I ):

LET number be an integer between 1 and 4000 LET symbol be RomanNumeral.values()[0] LET result be an empty String WHILE number > 0: IF symbol's value <= number: append the result with the symbol's name subtract symbol's value from number ELSE: pick the next symbol

5.1. la mise en oeuvre

Ensuite, nous pouvons maintenant implémenter l'algorithme:

public static String arabicToRoman(int number) { if ((number  4000)) { throw new IllegalArgumentException(number + " is not in range (0,4000]"); } List romanNumerals = RomanNumeral.getReverseSortedValues(); int i = 0; StringBuilder sb = new StringBuilder(); while ((number > 0) && (i < romanNumerals.size())) { RomanNumeral currentSymbol = romanNumerals.get(i); if (currentSymbol.getValue() <= number) { sb.append(currentSymbol.name()); number -= currentSymbol.getValue(); } else { i++; } } return sb.toString(); }

5.2. Tester

Enfin, nous pouvons tester l'implémentation:

@Test public void given1999Arabic_WhenConvertingToRoman_ThenReturnMCMXCIX() { int arabic1999 = 1999; String result = RomanArabicConverter.arabicToRoman(arabic1999); assertThat(result).isEqualTo("MCMXCIX"); }

6. Conclusion

Dans cet article rapide, nous avons montré comment convertir entre les chiffres romains et arabes.

Nous avons utilisé une énumération pour représenter l'ensemble des chiffres romains et nous avons créé une classe utilitaire pour effectuer les conversions.

L'implémentation complète et tous les tests peuvent être trouvés sur GitHub.