1. Обзор
В этом уроке мы увидим, как проверить, содержит ли строка все буквы алфавита или нет.
Вот простой пример: « Фермер Джек понял, что большие желтые одеяла стоят дорого.
” – который на самом деле содержит все буквы алфавита.
Мы обсудим три подхода.
Во-первых, мы смоделируем алгоритм, используя императивный подход. Затем будут использоваться регулярные выражения. И, наконец, мы воспользуемся более декларативным подходом, используя Java 8.
Кроме того, мы обсудим большую сложность используемых подходов.
2. Императивный алгоритм
Реализуем императивный алгоритм. Для этого, во-первых, мы создадим логический массив посещений. Затем мы пройдемся по входной строке символ за символом и пометим символ как посещенный.
Обратите внимание, что прописные
и строчные буквы
считаются одинаковыми. Таким образом, индекс 0 представляет и A, и a, а индекс 25 представляет и Z, и z.
Наконец, мы проверим, установлены ли для всех символов в массиве посещений значение true:
public class EnglishAlphabetLetters {
public static boolean checkStringForAllTheLetters(String input) {
int index = 0;
boolean[] visited = new boolean[26];
for (int id = 0; id < input.length(); id++) {
if ('a' <= input.charAt(id) && input.charAt(id) <= 'z') {
index = input.charAt(id) - 'a';
} else if ('A' <= input.charAt(id) && input.charAt(id) <= 'Z') {
index = input.charAt(id) - 'A';
}
visited[index] = true;
}
for (int id = 0; id < 26; id++) {
if (!visited[id]) {
return false;
}
}
return true;
}
}
Большая O-сложность этой программы равна O(n), где n
— длина строки.
Обратите внимание, что существует множество способов оптимизации алгоритма, например удаление букв из набора и прерывание, как только набор
становится пустым. Однако для целей упражнения этот алгоритм достаточно хорош.
3. Использование регулярных выражений
Используя регулярное выражение, мы можем легко получить те же результаты с помощью нескольких строк кода:
public static boolean checkStringForAllLetterUsingRegex(String input) {
return input.toLowerCase()
.replaceAll("[^a-z]", "")
.replaceAll("(.)(?=.*\\1)", "")
.length() == 26;
}
Здесь мы сначала удаляем из ввода
все символы, кроме букв алфавита . Затем мы удаляем повторяющиеся символы. Наконец, мы считаем буквы и убеждаемся, что у нас их все, 26.
Несмотря на меньшую производительность, Big-O-Complexity этого подхода также стремится к O(n).
4. Поток Java 8
Используя функции Java 8, мы можем легко добиться того же результата более компактным и декларативным способом, используя фильтр
Stream и отдельные
методы:
public static boolean checkStringForAllLetterUsingStream(String input) {
long c = input.toLowerCase().chars()
.filter(ch -> ch >= 'a' && ch <= 'z')
.distinct()
.count();
return c == 26;
}
Сложность Big-O этого подхода также будет O(n).
4. Тестирование
Давайте проверим счастливый путь для нашего алгоритма:
@Test
public void givenString_whenContainsAllCharacter_thenTrue() {
String sentence = "Farmer jack realized that big yellow quilts were expensive";
assertTrue(EnglishAlphabetLetters.checkStringForAllTheLetters(sentence));
}
Здесь предложение
содержит все буквы алфавита, поэтому в результате мы ожидаем, что оно истинно
.
5. Вывод
В этом уроке мы рассмотрели, как проверить, содержит ли строка все буквы алфавита .
Сначала мы увидели несколько способов реализовать это с помощью традиционного императивного программирования, регулярных выражений и потоков Java 8.
Полный исходный код доступен на GitHub .