文字列が回文かどうかを調べる

1前書き

この記事では、与えられた String が回文であるかどうかをJavaを使って確認する方法を説明します。

  • 回文とは、単語、句、数字、または「マダム」や「レースカー」のように、前方** と同じ方向に逆方向に読むその他の文字のシーケンスです。

2ソリューション

次のセクションでは、指定された String が回文であるかどうかを確認するさまざまな方法について説明します。

2.1. 簡単なアプローチ

一度に1文字ずつ、与えられた string の順方向および逆方向の反復を同時に開始できます。一致があれば、ループは継続します。そうでなければ、ループは終了します。

public boolean isPalindrome(String text) {
    String clean = text.replaceAll("\\s+", "").toLowerCase();
    int length = clean.length();
    int forward = 0;
    int backward = length - 1;
    while (backward > forward) {
        char forwardChar = clean.charAt(forward++);
        char backwardChar = clean.charAt(backward--);
        if (forwardChar != backwardChar)
            return false;
    }
    return true;
}

2.2. 文字列を反転する

このユースケースに適合する実装はいくつかあります。回文をチェックするときに StringBuilder および StringBuffer クラスのAPIメソッドを使用することも、これらのクラスを使用せずに String を逆にすることもできます。

まず、ヘルパーAPIなしのコード実装を見てみましょう。

public boolean isPalindromeReverseTheString(String text) {
    StringBuilder reverse = new StringBuilder();
    String clean = text.replaceAll("\\s+", "").toLowerCase();
    char[]plain = clean.toCharArray();
    for (int i = plain.length - 1; i >= 0; i--) {
        reverse.append(plain[i]);
    }
    return (reverse.toString()).equals(clean);
}

上記のスニペットでは、最後の文字から指定された String を繰り返し、最初の文字までの各文字を次の文字に追加して、指定された__Stringを反転させるだけです。

最後に、与えられた String と逆の String. の間の等価性をテストします。

APIメソッドを使用しても同じ動作を実現できます。

簡単なデモを見てみましょう。

public boolean isPalindromeUsingStringBuilder(String text) {
    String clean = text.replaceAll("\\s+", "").toLowerCase();
    StringBuilder plain = new StringBuilder(clean);
    StringBuilder reverse = plain.reverse();
    return (reverse.toString()).equals(clean);
}

public boolean isPalindromeUsingStringBuffer(String text) {
    String clean = text.replaceAll("\\s+", "").toLowerCase();
    StringBuffer plain = new StringBuffer(clean);
    StringBuffer reverse = plain.reverse();
    return (reverse.toString()).equals(clean);
}

コードスニペットでは、 StringBuilder および StringBuffer APIから reverse() メソッドを呼び出して、指定された String を逆にし、等価性をテストします。

2.3. Stream APIを使用する

ソリューションを提供するために IntStream を使用することもできます。

public boolean isPalindromeUsingIntStream(String text) {
    String temp  = text.replaceAll("\\s+", "").toLowerCase();
    return IntStream.range(0, temp.length()/2)
      .noneMatch(i -> temp.charAt(i) != temp.charAt(temp.length() - i - 1));
}

上記のスニペットでは、 String の両端からの文字ペアがどれも Predicate 条件を満たさないことを確認します。

2.4. 再帰を使う

再帰は、この種の問題を解決するための非常に一般的な方法です。示された例では、与えられた String を再帰的に繰り返し、それが回文であるかどうかを調べます。

public boolean isPalindromeRecursive(String text){
    String clean = text.replaceAll("\\s+", "").toLowerCase();
    return recursivePalindrome(clean,0,clean.length()-1);
}

private boolean recursivePalindrome(String text, int forward, int backward) {
    if (forward == backward) {
        return true;
    }
    if ((text.charAt(forward)) != (text.charAt(backward))) {
        return false;
    }
    if (forward < backward + 1) {
        return recursivePalindrome(text, forward + 1, backward - 1);
    }

    return true;
}

3結論

このクイックチュートリアルでは、与えられた String が回文であるかどうかを調べる方法を見ました。

いつものように、この記事のコード例はhttps://github.com/eugenp/tutorials/tree/master/java-strings[over on GitHub]にあります。