检查字符串是否是Java中的Pangram

Check if a String is a Pangram in Java

1.概述

在本教程中,我们将学习不使用简单的Java程序来检查给定的字符串是否是有效的pangramor。 Pangram是任何包含给定字母集的所有字母至少一次的字符串。

2. Pangrams

Pangram不仅适用于英语,而且适用于具有固定字符集的任何其他语言。

例如,一个常见的英语翻译是"一只快速的棕色狐狸跳过懒狗"。同样,这些语言也可以使用其他语言。

3.使用for循环

首先,让我们尝试一个forloop。我们将为字母的每个字符填充一个带有标记的布尔数组。

当标记数组中的所有值都设置为true时,代码将返回true:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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;
}

让我们测试一下实现:

1
2
3
4
5
@Test
public void givenValidString_isPanagram_shouldReturnSuccess() {
    String input ="Two driven jocks help fax my big quiz";
    assertTrue(Pangram.isPangram(input));  
}

4.使用Java流

另一种方法涉及使用Java Streams API。我们可以从给定的输入文本中创建过滤的字符流,并使用该流创建字母映射。

如果Map的大小等于字母的大小,则代码返回成功。对于英语,预期大小为26:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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;
}

并且,当然,让我们测试一下:

1
2
3
4
5
@Test
public void givenValidString_isPangramWithStreams_shouldReturnSuccess() {
    String input ="The quick brown fox jumps over the lazy dog";
    assertTrue(Pangram.isPangramWithStreams(input));
}

5.修改完美的Pangram

完美的pangram与普通的pangram有点不同。完美的字母由字母表中的每个字母恰好组成一次,而字母的字母则至少由一次组成。

当Map大小等于字母大小并且字母中每个字符的频率正好为1时,代码返回true:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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);
}

让我们测试一下:

1
2
3
4
5
@Test
public void givenPerfectPangramString_isPerfectPangram_shouldReturnSuccess() {
    String input ="abcdefghijklmNoPqrStuVwxyz";
    assertTrue(Pangram.isPerfectPangram(input));
}

一个完美的人物应该每个角色恰好有一次。因此,我们之前的pangram应该会失败:

1
2
String input ="Two driven jocks help fax my big quiz";
assertFalse(Pangram.isPerfectPangram(input));

在上面的代码中,给定的字符串输入有多个重复项,就像它有两个o。因此,输出为假。

5.结论

在本文中,我们介绍了各种解决方案方法,以找出给定的字符串是否是有效的字符集。

我们还讨论了pangram的另一种味道,称为完善pangram,以及如何以编程方式识别它。

该代码示例可在GitHub上获得。