文字列がJavaのパングラムかどうかを確認する

1. 概要

このチュートリアルでは、特定の文字列が有効なパングラムであるか、単純なJavaプログラムを使用していないかを確認する方法を学習します。 * https://en.wikipedia.org/wiki/Pangram [pangram]は、指定されたアルファベットのすべての文字を少なくとも1回設定した文字列です。

2. パングラム

パングラムは、英語だけでなく、文字セットが固定されている他の言語にも適用できます。
たとえば、一般的に知られている英語のパングラムは、「茶色のキツネが怠zyな犬を飛び越える」です。 同様に、これらはhttp://clagnut.com/blog/2380/[other]言語でも利用可能です。

3. _for_ループの使用

最初に、https://www.baeldung.com/java-loops [__for __loop] __.__を試してみましょう。アルファベットの各文字のマーカーを使用して、__Boolean __arrayを作成します。
マーカー配列のすべての値が_true_に設定されている場合、コードは__true ___を返します。
public static boolean isPangram(String str) {
    if (str == null) {
        return false;
    }
    Boolean[] alphabetMarker = new Boolean[ALPHABET_COUNT];
    Arrays.fill(alphabetMarker, false);
    int alphabetIndex = 0;
    str = str.toUpperCase();
    for (int i = 0; i < str.length(); i++) {
        if ('A' <= str.charAt(i) && str.charAt(i) <= 'Z') {
            alphabetIndex = str.charAt(i) - 'A';
            alphabetMarker[alphabetIndex] = true;
        }
    }
    for (boolean index : alphabetMarker) {
        if (!index) {
            return false;
        }
    }
    return true;
}
実装をテストしましょう:
@Test
public void givenValidString_isPanagram_shouldReturnSuccess() {
    String input = "Two driven jocks help fax my big quiz";
    assertTrue(Pangram.isPangram(input));
}

4. Javaストリームの使用

別のアプローチでは、https://www.baeldung.com/java-8-streams-introduction [Java Streams API]を使用します。 **指定された入力テキストからフィルタリングされた文字ストリームを作成し、ストリームを使用してアルファベット_Map_を作成できます** __.__
_Map_のサイズがアルファベットのサイズに等しい場合、コードは成功を返します。 英語の場合、予想されるサイズは26です。
public static boolean isPangramWithStreams(String str) {
    if (str == null) {
        return false;
    }
    String strUpper = str.toUpperCase();

    Stream<Character> filteredCharStream = strUpper.chars()
      .filter(item -> ((item >= 'A' && item <= 'Z')))
      .mapToObj(c -> (char) c);

    Map<Character, Boolean> alphabetMap =
      filteredCharStream.collect(Collectors.toMap(item -> item, k -> Boolean.TRUE, (p1, p2) -> p1));

    return alphabetMap.size() == ALPHABET_COUNT;
}
そして、もちろん、テストしてみましょう:
@Test
public void givenValidString_isPangramWithStreams_shouldReturnSuccess() {
    String input = "The quick brown fox jumps over the lazy dog";
    assertTrue(Pangram.isPangramWithStreams(input));
}

5. 完全なパングラムのための修正

完全なパングラムは、通常のパングラムとは少し異なります。 *完全なパングラムは、パングラムの少なくとも1回ではなく、アルファベットの各文字で1回だけ構成されます。
_Map_サイズとアルファベットサイズの両方が等しく、アルファベットの各文字の頻度が正確に1である場合、コードは__true ___を返します。
public static boolean isPerfectPangram(String str) {
    if (str == null) {
        return false;
    }
    String strUpper = str.toUpperCase();

    Stream<Character> filteredCharStream = strUpper.chars()
        .filter(item -> ((item >= 'A' && item <= 'Z')))
        .mapToObj(c -> (char) c);
    Map<Character, Long> alphabetFrequencyMap =
      filteredCharStream.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));

    return alphabetFrequencyMap.size() == ALPHABET_COUNT &&
      alphabetFrequencyMap.values().stream().allMatch(item -> item == 1);
}
そしてテストしてみましょう:
@Test
public void givenPerfectPangramString_isPerfectPangram_shouldReturnSuccess() {
    String input = "abcdefghijklmNoPqrStuVwxyz";
    assertTrue(Pangram.isPerfectPangram(input));
}
完璧なパングラムには、各キャラクターが1回だけ必要です。 したがって、以前のパングラムは失敗するはずです。
String input = "Two driven jocks help fax my big quiz";
assertFalse(Pangram.isPerfectPangram(input));
上記のコードでは、指定された文字列入力には2つのoがあるように、いくつかの重複があります。 したがって、出力は_false_です。

5. 結論

この記事では、特定の文字列が有効なパングラムであるかどうかを確認するためのさまざまなソリューションアプローチについて説明しました。
また、完璧なパングラムと呼ばれるパングラムの他のフレーバーと、プログラムで識別する方法についても説明しました。
コードサンプルはhttps://github.com/eugenp/tutorials/tree/master/java-strings-2[overit on GitHub]で入手できます。