Konvertieren zwischen römischen und arabischen Ziffern in Java

1. Einleitung

Die alten Römer entwickelten ein eigenes numerisches System, das römische Ziffern genannt wurde. Das System verwendet Buchstaben mit unterschiedlichen Werten, um Zahlen darzustellen. In einigen kleineren Anwendungen werden heute noch römische Ziffern verwendet.

In diesem Tutorial implementieren wir einfache Konverter, die Zahlen von einem System in das andere transformieren.

2. Römische Ziffern

Im römischen System haben wir 7 Symbole, die Zahlen darstellen :

  • Ich vertrete 1
  • V steht für 5
  • X steht für 10
  • L steht für 50
  • C steht für 100
  • D steht für 500
  • M steht für 1000

Ursprünglich repräsentierten die Leute eine 4 mit IIII oder 40 mit XXXX. Das Lesen kann sehr unangenehm sein. Es ist auch leicht, vier Symbole nebeneinander mit drei Symbolen zu verwechseln.

Römische Ziffern verwenden eine subtraktive Notation , um solche Fehler zu vermeiden. Anstatt viermal eins (IIII) zu sagen, kann man sagen, dass es eins weniger als fünf (IV) ist.

Wie wichtig ist es aus unserer Sicht? Dies ist wichtig, da wir nicht einfach Symbol für Symbol Zahlen hinzufügen müssen, sondern möglicherweise das nächste Symbol überprüfen müssen, um festzustellen, ob die Zahl addiert oder subtrahiert werden soll.

3. Modell

Definieren wir eine Aufzählung zur Darstellung der römischen Ziffern:

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()); } }

Beachten Sie, dass wir zusätzliche Symbole definiert haben, um die subtraktive Notation zu erleichtern. Wir haben auch eine zusätzliche Methode namens getReverseSortedValues ​​() definiert .

Mit dieser Methode können wir die definierten römischen Ziffern explizit in absteigender Reihenfolge der Werte abrufen.

4. Römisch bis Arabisch

Römische Ziffern können nur ganze Zahlen zwischen 1 und 4000 darstellen . Wir können den folgenden Algorithmus verwenden, um eine römische Zahl in eine arabische Zahl umzuwandeln (durch Symbole in umgekehrter Reihenfolge von M nach I iterieren ):

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. Implementierung

Als nächstes können wir den Algorithmus in Java implementieren:

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. Prüfung

Schließlich können wir die Implementierung testen:

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

5. Arabisch zu Römisch

Wir können den folgenden Algorithmus verwenden, um arabische in römische Ziffern umzuwandeln (durch Symbole in umgekehrter Reihenfolge von M nach I iterieren ):

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. Implementierung

Als nächstes können wir nun den Algorithmus implementieren:

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. Prüfung

Schließlich können wir die Implementierung testen:

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

6. Fazit

In diesem kurzen Artikel haben wir gezeigt, wie man zwischen römischen und arabischen Ziffern konvertiert.

Wir haben eine Aufzählung verwendet , um die Menge der römischen Ziffern darzustellen, und wir haben eine Dienstprogrammklasse erstellt, um die Konvertierungen durchzuführen.

Die vollständige Implementierung und alle Tests finden Sie auf GitHub.