1概要

このチュートリアルでは、金額をJavaで単語表現に変換する方法を説明します。


Tradukisto

という外部ライブラリを介して、カスタム実装がどのように見えるかについても説明します。


2実装

最初に私たち自身の実装から始めましょう。 ** 最初のステップは、以下の要素を持つ2つの

String

配列を宣言することです。

public static String[]ones = {
  "", "one", "two", "three", "four",
  "five", "six", "seven", "eight",
  "nine", "ten", "eleven", "twelve",
  "thirteen", "fourteen", "fifteen",
  "sixteen", "seventeen", "eighteen",
  "nineteen"
};

public static String[]tens = {
  "",         //0
  "",         //1
  "twenty",   //2
  "thirty",   //3
  "forty",    //4
  "fifty",    //5
  "sixty",    //6
  "seventy",  //7
  "eighty",   //8
  "ninety"    //9
};

入力を受け取ったら、無効な値(ゼロと負の値)を処理する必要があります。 ** 有効な入力を受け取ったら、ドルとセントの数を変数に抽出します。

 long dollars = (long) money;
 long cents = Math.round((money - dollars) **  100);

与えられた数が20未満の場合は、インデックスに基づいて配列から適切な

ones’

要素を取得します。

if (n < 20) {
    return ones[(int) n];
}

100未満の数値に対しても同様のアプローチを使用しますが、今度は

tens

配列も使用する必要があります。

if (n < 100) {
    return tens[(int) n/10]
      + ((n % 10 != 0) ? " " : "")
      + ones[(int) n % 10];
}

私たちは千未満の数のためにこれを同様にします。

次に、以下に示すように、再帰呼び出しを使用して100万未満の数を処理します。

if (n < 1__000__000) {
    return convert(n/1000) + " thousand" + ((n % 1000 != 0) ? " " : "")
      + convert(n % 1000);
}

同じアプローチが、10億未満の数字にも使用されます。

これは、この変換を行うために呼び出すことができる主なメソッドです。

 public static String getMoneyIntoWords(double money) {
    long dollars = (long) money;
    long cents = Math.round((money - dollars) **  100);
    if (money == 0D) {
        return "";
    }
    if (money < 0) {
        return INVALID__INPUT__GIVEN;
    }
    String dollarsPart = "";
    if (dollars > 0) {
        dollarsPart = convert(dollars)
          + " dollar"
          + (dollars == 1 ? "" : "s");
    }
    String centsPart = "";
    if (cents > 0) {
        if (dollarParts.length() > 0) {
            centsPart = " and ";
        }
        centsPart += convert(cents) + " cent" + (cents == 1 ? "" : "s");
    }
    return dollarsPart + centsPart;
}

機能することを確認するために、コードをテストしましょう。

@Test
public void whenGivenDollarsAndCents__thenReturnWords() {
    String expectedResult
     = "nine hundred twenty four dollars and sixty cents";

    assertEquals(
      expectedResult,
      NumberWordConverter.getMoneyIntoWords(924.6));
}

@Test
public void whenTwoBillionDollarsGiven__thenReturnWords() {
    String expectedResult
      = "two billion one hundred thirty three million two hundred"
        + " forty seven thousand eight hundred ten dollars";

    assertEquals(
      expectedResult,
      NumberWordConverter.getMoneyIntoWords(2__133__247__810));
}

@Test
public void whenThirtyMillionDollarsGiven__thenReturnWords() {
    String expectedResult
      = "thirty three million three hundred forty eight thousand nine hundred seventy eight dollars";
    assertEquals(
      expectedResult,
      NumberWordConverter.getMoneyIntoWords(33__348__978));
}

また、いくつかのエッジケースをテストして、それらもカバーしていることを確認しましょう。

@Test
public void whenZeroDollarsGiven__thenReturnEmptyString() {
    assertEquals("", NumberWordConverter.getMoneyIntoWords(0));
}

@Test
public void whenNoDollarsAndNineFiveNineCents__thenCorrectRounding() {
    assertEquals(
      "ninety six cents",
      NumberWordConverter.getMoneyIntoWords(0.959));
}

@Test
public void whenNoDollarsAndOneCent__thenReturnCentSingular() {
    assertEquals(
      "one cent",
      NumberWordConverter.getMoneyIntoWords(0.01));
}


3図書館を利用する

独自のアルゴリズムを実装したので、今度は既存のライブラリを使用してこの変換を行います。



Tradukisto


はJava 8のライブラリで、数字を単語の表現に変換するのに役立ちます。まず、それを私たちのプロジェクトにインポートする必要があります(このライブラリーの最新バージョンはhttps://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22pl.allegro.finance%22にあります)。 %20AND%20a%3A%22tradukisto%22[ここ]):

<dependency>
    <groupId>pl.allegro.finance</groupId>
    <artifactId>tradukisto</artifactId>
    <version>1.0.1</version>
</dependency>

この変換を行うには、

MoneyConverters

‘s

asWords()

メソッドを使用します。

public String getMoneyIntoWords(String input) {
    MoneyConverters converter = MoneyConverters.ENGLISH__BANKING__MONEY__VALUE;
    return converter.asWords(new BigDecimal(input));
}

簡単なテストケースでこのメソッドをテストしましょう。

@Test
public void whenGivenDollarsAndCents__thenReturnWordsVersionTwo() {
    assertEquals(
      "three hundred ten £ 00/100",
      NumberWordConverter.getMoneyIntoWords("310"));
}

これを行うにはhttp://site.icu-project.org/home[ICU4J]ライブラリを使用することもできますが、これは大規模なものであり、この記事の範囲外の他の多くの機能が付属しています。

ただし、Unicodeとグローバリゼーションのサポートが必要かどうかを調べてください。


4結論

この簡単な記事では、合計金額を単語に変換する方法について2つのアプローチを説明しました。

ここで説明したすべての例のためのコード、そしてもっとたくさんのものがhttps://github.com/eugenp/tutorials/tree/master/algorithms-miscellaneous-2[over on GitHub]にあります。