«1. Обзор
В этом уроке мы научимся проверять, является ли данная строка допустимой панграммой или нет, используя простую программу Java. Панграмма — это любая строка, содержащая все буквы заданного набора алфавитов хотя бы один раз.
2. Панграммы
Панграммы применимы не только к английскому языку, но и к любому другому языку, имеющему фиксированный набор символов.
Например, широко известная английская панграмма звучит так: «Быстрая коричневая лиса перепрыгивает через ленивую собаку». Точно так же они доступны и на других языках.
3. Использование цикла for
Сначала попробуем цикл 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. Мы можем создать отфильтрованный поток символов из заданного входного текста и создать карту алфавита, используя этот поток.
Код возвращает успех, если размер Карты равен размеру алфавита. Для английского языка ожидаемый размер 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. Модификация для идеальных панграмм
Идеальная панграмма немного отличается от обычной панграммы . Идеальная панграмма состоит из каждой буквы алфавита ровно один раз, в отличие от по крайней мере одного раза для панграммы.
Код возвращает 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));
}
Идеальная панграмма должна иметь каждый символ ровно один раз. Таким образом, наша предыдущая панграмма должна потерпеть неудачу:
String input = "Two driven jocks help fax my big quiz";
assertFalse(Pangram.isPerfectPangram(input));
В приведенном выше коде заданная строка ввода имеет несколько дубликатов, как если бы у нее было два o. Следовательно, вывод ложный.
5. Заключение
В этой статье мы рассмотрели различные подходы к решению, чтобы выяснить, является ли данная строка допустимой панграммой или нет.
Мы также обсудили еще одну разновидность панграмм, которая называется идеальной панграммой, и как ее идентифицировать программно.
Пример кода доступен на GitHub.