1. Обзор
В этом уроке мы научимся проверять, является ли данная строка допустимой pangram или нет, используя простую программу Java./| pangram – это любая строка, содержащая все буквы заданного набора алфавитов хотя бы один раз.
2. Панграммы
Панграммы применимы не только к английскому языку, но и к любому другому языку, имеющему фиксированный набор символов.
Например, общеизвестная английская панграмма – “Быстрая бурая лиса перепрыгивает через ленивую собаку”. Точно так же они доступны и на других языках.
3. Использование цикла for
Во-первых, давайте попробуем для цикла . Мы заполним Логический массив маркерами для каждого символа алфавита.
Код возвращает 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
Альтернативный подход предполагает использование API Java Streams . Мы можем создать отфильтрованный поток символов из заданного входного текста и создать алфавит Карту , используя поток .
Код возвращает успех, если размер Карты равен размеру алфавита. Для английского языка ожидаемый размер составляет 26:
public static boolean isPangramWithStreams(String str) { if (str == null) { return false; } String strUpper = str.toUpperCase(); StreamfilteredCharStream = strUpper.chars() .filter(item -> ((item >= 'A' && item <= 'Z'))) .mapToObj(c -> (char) c); Map 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. Модификация для идеальных Панграмм
Идеальная панграмма немного отличается от обычной панграммы. совершенная панграмма состоит из каждой буквы алфавита ровно один раз в отличие от по крайней мере одного раза для панграммы.
Код возвращает true , когда размер Map равен размеру алфавита, а частота каждого символа в алфавите равна ровно одному:
public static boolean isPerfectPangram(String str) { if (str == null) { return false; } String strUpper = str.toUpperCase(); StreamfilteredCharStream = strUpper.chars() .filter(item -> ((item >= 'A' && item <= 'Z'))) .mapToObj(c -> (char) c); Map 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)); }
Идеальная панграмма должна иметь каждый символ ровно один раз. Итак, наша предыдущая панграмма должна потерпеть неудачу:
String input = "Two driven jocks help fax my big quiz"; assertFalse(Pangram.isPerfectPangram(input));
В приведенном выше коде данный строковый ввод имеет несколько дубликатов, например, два o. Следовательно, вывод будет false .
5. Заключение
В этой статье мы рассмотрели различные подходы к решению, чтобы выяснить, является ли данная строка допустимой панграммой или нет.
Мы также обсудили еще один вид панграмм, который называется perfect pangram, и как определить его программно.
Пример кода доступен на GitHub .