Mengubah Angka Romawi dan Arab di Jawa

1. Perkenalan

Bangsa Romawi kuno mengembangkan sistem numerik mereka sendiri yang disebut angka Romawi. Sistem menggunakan huruf dengan nilai berbeda untuk merepresentasikan angka. Angka Romawi masih digunakan sampai sekarang di beberapa aplikasi kecil.

Dalam tutorial ini, kami akan menerapkan konverter sederhana yang akan mengubah angka dari satu sistem ke sistem lainnya.

2. Angka Romawi

Dalam sistem Romawi, kami memiliki 7 simbol yang mewakili angka :

  • Saya mewakili 1
  • V mewakili 5
  • X mewakili 10
  • L mewakili 50
  • C mewakili 100
  • D mewakili 500
  • M mewakili 1000

Awalnya, orang dulu mewakili angka 4 dengan IIII atau 40 dengan XXXX. Ini bisa sangat tidak nyaman untuk dibaca. Juga mudah untuk salah mengira empat simbol di samping satu sama lain untuk tiga simbol.

Angka romawi menggunakan notasi subtraktif untuk menghindari kesalahan seperti itu. Dari pada mengatakan empat kali satu (IIII), bisa dikatakan satu kurang dari lima (IV).

Seberapa penting dari sudut pandang kita? Ini penting karena alih-alih hanya menambahkan simbol angka demi simbol, kita mungkin perlu memeriksa simbol berikutnya untuk menentukan apakah angka tersebut harus ditambah atau dikurangi.

3. Model

Mari definisikan enum untuk mewakili Angka Romawi:

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

Perhatikan bahwa kita telah mendefinisikan simbol tambahan untuk membantu notasi subtraktif. Kami juga telah mendefinisikan metode tambahan bernama getReverseSortedValues ​​() .

Metode ini akan memungkinkan kita untuk secara eksplisit mengambil angka Romawi yang ditentukan dalam urutan nilai menurun.

4. Romawi ke Arab

Angka romawi hanya dapat mewakili bilangan bulat antara 1 sampai 4000 . Kita dapat menggunakan algoritme berikut untuk mengubah angka Romawi menjadi angka Arab (mengiterasi simbol dalam urutan terbalik dari M ke 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. Penerapan

Selanjutnya, kita dapat mengimplementasikan algoritme di 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. Uji

Akhirnya, kita bisa menguji implementasinya:

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

5. Arab ke Romawi

Kita dapat menggunakan algoritma berikut untuk mengonversi dari angka Arab ke Romawi (mengiterasi simbol dalam urutan terbalik dari M ke 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. Penerapan

Selanjutnya, kita sekarang dapat mengimplementasikan algoritme:

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

Akhirnya, kita bisa menguji implementasinya:

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

6. Kesimpulan

Dalam artikel singkat ini, kami telah menunjukkan cara mengonversi antara angka Romawi dan Arab.

Kami telah menggunakan enum untuk mewakili himpunan angka Romawi dan kami telah membuat kelas utilitas untuk melakukan konversi.

Implementasi lengkap dan semua pengujian dapat ditemukan di GitHub.