Menukar Antara Angka Rom dan Arab di Jawa

1. Pengenalan

Orang Rom kuno mengembangkan sistem numerik mereka sendiri yang disebut angka Rom. Sistem menggunakan huruf dengan nilai yang berbeza untuk mewakili nombor. Angka Rom masih digunakan hari ini dalam beberapa aplikasi kecil.

Dalam tutorial ini, kami akan melaksanakan penukar sederhana yang akan mengubah nombor dari satu sistem ke sistem yang lain.

2. Angka Rom

Dalam sistem Rom, kita mempunyai 7 simbol yang mewakili nombor :

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

Pada asalnya, orang biasa mewakili 4 dengan IIII atau 40 dengan XXXX. Ini agak tidak selesa untuk dibaca. Juga mudah untuk salah empat simbol di sebelah satu sama lain untuk tiga simbol.

Angka Rom menggunakan notasi tolak untuk mengelakkan kesilapan tersebut. Daripada mengatakan empat kali satu (IIII), seseorang boleh mengatakan bahawa itu satu yang kurang daripada lima (IV).

Bagaimana ia penting dari perspektif kita? Ini penting kerana daripada hanya menambahkan simbol nombor dengan simbol, kita mungkin perlu menyemak simbol seterusnya untuk menentukan apakah nombor tersebut harus ditambah atau dikurangkan.

3. Model

Mari tentukan enum untuk mewakili Angka Rom:

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 bahawa kami telah menentukan simbol tambahan untuk membantu notasi kurang menarik. Kami juga telah menentukan kaedah tambahan bernama getReverseSortedValues ​​() .

Kaedah ini akan membolehkan kita secara eksplisit mengambil angka Rom yang ditentukan dalam urutan nilai menurun.

4. Bahasa Rom ke Bahasa Arab

Angka Rom hanya boleh mewakili bilangan bulat antara 1 hingga 4000 . Kita boleh menggunakan algoritma berikut untuk menukar angka Rom ke nombor Arab (berulang melalui 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. Pelaksanaan

Seterusnya, kita dapat menerapkan algoritma 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 dapat menguji pelaksanaannya:

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

5. Bahasa Arab ke Bahasa Rom

Kita boleh menggunakan algoritma berikut untuk menukar dari angka Arab ke angka Rom (berulang melalui 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. Pelaksanaan

Seterusnya, kita sekarang dapat menerapkan algoritma:

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 dapat menguji pelaksanaannya:

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

6. Kesimpulannya

Dalam artikel ringkas ini, kami telah menunjukkan cara menukar antara angka Rom dan Arab.

Kami telah menggunakan enum untuk mewakili kumpulan angka Rom dan kami telah membuat kelas utiliti untuk melakukan penukaran.

Pelaksanaan yang lengkap dan semua ujian boleh didapati di GitHub.