Konvertering mellom romerske og arabiske tall i Java

1. Introduksjon

De gamle romerne utviklet sitt eget numeriske system kalt romertall. Systemet bruker bokstaver med forskjellige verdier for å representere tall. Romerske tall brukes fortsatt i dag i noen mindre applikasjoner.

I denne opplæringen implementerer vi enkle omformere som vil transformere tall fra ett system til det andre.

2. Romerske tall

I det romerske systemet har vi det 7 symboler som representerer tall:

  • Jeg representerer 1
  • V representerer 5
  • X representerer 10
  • L representerer 50
  • C representerer 100
  • D representerer 500
  • M representerer 1000

Opprinnelig representerte folk en 4 med IIII eller 40 med XXXX. Dette kan være ganske ubehagelig å lese. Det er også lett å feile fire symboler ved siden av hverandre for tre symboler.

Romerske tall bruker subtraktiv notasjon for å unngå slike feil. I stedet for å si fire ganger en (IIII), kan man si at det er en mindre enn fem (IV).

Hvordan er det viktig fra vårt perspektiv? Det er viktig fordi i stedet for å bare legge til tall symbol for symbol, må vi kanskje sjekke neste symbol for å avgjøre om tallet skal legges til eller trekkes fra.

3. Modell

La oss definere et enum som skal representere de romerske tallene:

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); privat int verdi; RomanNumeral (int-verdi) {this.value = verdi; } public int getValue () {returverdi; } offentlig statisk liste getReverseSortedValues ​​() {return Arrays.stream (values ​​()) .sorted (Comparator.comparing ((RomanNumeral e) -> e.value) .reversed ()) .collect (Collectors.toList ()); }}

Legg merke til at vi har definert flere symboler for å hjelpe deg med subtraktiv notasjon. Vi har også definert en ekstra metode som heter getReverseSortedValues ​​().

Denne metoden lar oss eksplisitt hente de definerte romertallene i synkende verdierekkefølge.

4. Romersk til arabisk

Romerske tall kan bare representere heltall mellom 1 og 4000. Vi kan bruke følgende algoritme til å konvertere et romertall til et arabisk tall (gjentas gjennom symboler i omvendt rekkefølge fra M til Jeg):

LET-tallet er inngangen Streng som representerer et romertall LET-symbol settes initialt til 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 tallets begynnelse ELSE: sett symbol til neste symbol

4.1. Gjennomføring

Deretter kan vi implementere algoritmen i Java:

public static int romanToArabic (String input) {String romanNumeral = input.toUpperCase (); int resultat = 0; Liste romanNumerals = RomanNumeral.getReverseSortedValues ​​(); int i = 0; mens ((romanNumeral.length ()> 0) && (i 0) {kast nytt IllegalArgumentException (input + "kan ikke konverteres til et romertall");} returnerer resultat;}

4.2. Test

Til slutt kan vi teste implementeringen:

@Test offentlig ugyldig gitt2018Roman_WhenConvertingToArabic_ThenReturn2018 () {String roman2018 = "MMXVIII"; int resultat = RomanArabicConverter.romanToArabic (roman2018); assertThat (resultat) .isEqualTo (2018); }

5. Arabisk til romersk

Vi kan bruke følgende algoritme til å konvertere fra arabisk til romertall (iterere gjennom symboler i omvendt rekkefølge fra M til Jeg):

LET-nummer være et heltall mellom 1 og 4000 LET-symbol være RomanNumeral.values ​​() [0] LET-resultat være en tom streng WHILE-nummer> 0: IF-symbolets verdi <= nummer: legg til resultatet med symbolets navn, trekk symbolets verdi fra tallet ELSE: velg neste symbol

5.1. Gjennomføring

Deretter kan vi nå implementere algoritmen:

offentlig statisk streng arabicToRoman (int-nummer) {if ((nummer 4000)) {kast ny IllegalArgumentException (nummer + "er ikke i området (0,4000]");} Liste 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 ()); nummer - = currentSymbol.getValue ();} ellers {i ++;}} returner sb.toString ();}

5.2. Test

Til slutt kan vi teste implementeringen:

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

6. Konklusjon

I denne raske artikkelen har vi vist hvordan du konverterer mellom romerske og arabiske tall.

Vi har brukt en enum for å representere settet med romerske tall, og vi har opprettet en nytteklasse for å utføre konverteringene.

Den komplette implementeringen og alle testene finner du på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found