Javaでローマ数字とアラビア数字を変換する

Javaでのローマ数字とアラビア数字の変換

1. 前書き

古代ローマ人はローマ数字と呼ばれる独自の数値システムを開発しました。 システムは、異なる値の文字を使用して数字を表します。 ローマ数字は、今日でもいくつかの小さなアプリケーションで使用されています。

このチュートリアルでは、simple converters that will transform numbers from one system to the other.を実装します

2. ローマ数字

ローマ数字のシステムでは、7 symbols that represent numbersがあります。

  • Iは1を表します

  • Vは5を表します

  • Xは10を表します

  • Lは50を表します

  • Cは100を表します

  • Dは500を表します

  • Mは1000を表します

元々、人々はIIIIで4を、XXXXで40を表していました。 これは非常に読みにくいものです。 また、隣り合った4つのシンボルを3つのシンボルと間違えやすいです。

このような間違いを避けるためにRoman numerals use subtractive notationfour times one(IIII)と言う代わりに、one less than five(IV)と言うことができます。

私たちの観点からどのように重要ですか? 単に記号ごとに数字を追加するのではなく、次の記号をチェックして、数字を加算するか減算するかを決定する必要がある場合があるため、重要です。

3. モデル

ローマ数字を表す列挙型を定義しましょう。

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

減法混色表記に役立つ追加の記号を定義していることに注意してください。 また、getReverseSortedValues()という名前の追加のメソッドを定義しました。

このメソッドにより、定義されたローマ数字を値の降順で明示的に取得できます。

4. ローマ数字からアラビア語

Roman numerals can only represent integers between 1 to 4000。 次のアルゴリズムを使用して、ローマ数字をアラビア数字に変換できます(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. 実装

次に、アルゴリズムを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 < romanNumerals.size())) {
        RomanNumeral symbol = romanNumerals.get(i);
        if (romanNumeral.startsWith(symbol.name())) {
            result += symbol.getValue();
            romanNumeral = romanNumeral.substring(symbol.name().length());
        } else {
            i++;
        }
    }

    if (romanNumeral.length() > 0) {
        throw new IllegalArgumentException(input + " cannot be converted to a Roman Numeral");
    }

    return result;
}

4.2. Test

最後に、実装をテストできます。

@Test
public void given2018Roman_WhenConvertingToArabic_ThenReturn2018() {
    String roman2018 = "MMXVIII";

    int result = RomanArabicConverter.romanToArabic(roman2018);

    assertThat(result).isEqualTo(2018);
}

5. アラビア語からローマ数字

次のアルゴリズムを使用して、アラビア数字からローマ数字に変換できます(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. 実装

次に、アルゴリズムを実装できます。

public static String arabicToRoman(int number) {
    if ((number <= 0) || (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. Test

最後に、実装をテストできます。

@Test
public void given1999Arabic_WhenConvertingToRoman_ThenReturnMCMXCIX() {
    int arabic1999 = 1999;

    String result = RomanArabicConverter.arabicToRoman(arabic1999);

    assertThat(result).isEqualTo("MCMXCIX");
}

6. 結論

この簡単な記事では、ローマ数字とアラビア数字を変換する方法を示しました。

ローマ数字のセットを表すためにenumを使用し、変換を実行するためのユーティリティクラスを作成しました。

完全な実装とすべてのテストはover on GitHubで見つけることができます。