Подсчет количества подстрок в строке с помощью JavaScript
Быстрый ответ
Чтобы определить количество вхождений подстроки в строку, следует использовать метод String.indexOf()
в цикле, обновляя индекс в процессе. Пример реализации дан ниже:
public int countOccurrences(String str, String sub) {
int count = 0;
for (int idx = 0; (idx = str.indexOf(sub, idx)) != -1; idx += sub.length()) {
count++;
}
return count;
}
При вызове у метода countOccurrences("example", "am")
будет возвращено количество вхождений, равное 1
.
Apache Commons Lang к Вашим услугам
С помощью метода StringUtils.countMatches
из Apache Commons Lang можно улучшить читаемость кода и упростить его:
public int countOccurrences(String str, String sub) {
return StringUtils.countMatches(str, sub);
}
Необходимо учесть, что использование данного способа потребует добавления библиотеки Apache Commons Lang в проектные зависимости.
Изощренное решение с помощью Stream и регулярных выражений
Сочетание Java Streams и регулярных выражений позволяет значительно расширить возможности:
public long countOccurrencesWithStream(String str, String regex) {
Pattern pattern = Pattern.compile(regex);
return pattern.splitAsStream(str).count() – 1;
}
При использовании данного метода следует проверить, что regex
правильно сформулирован и экранирован.
Не забывайте обновлять ваши индексы
Правильное обновление индекса после обнаружения совпадения поможет избежать вхождения в бесконечный цикл и других ошибок. Поиск следует прекращать, если значение lastIndex
становится равным -1
.
Визуализация
Визуализируем процесс поиска вхождений подстроки:
Основная строка (📜): "Игла в стоге сена, игла в куче игл, стог игл."
Подстрока (🔍): "игла"
Подсчет вхождений:
🔍 на 📜: Обнаружена первая "игла"! 🎯
🔍 на 📜: Обнаружена вторая "игла"! 🎯
🔍 на 📜: Обнаружена третья "игла"! 🎯
🔍 на 📜: Обнаружена четвертая "игла"! 🎯
Всего совпадений с "иглой": **4**.
Хитрость использования метода split
Метод split
с отрицательным лимитом может стать вашим "скрытым" инструментом:
public int countOccurrencesWithSplit(String str, String sub) {
return str.split(Pattern.quote(sub), -1).length – 1;
}
Применение метода split
позволяет избавиться от необходимости проводить дополнительную итерацию. Мы вычитаем одну позицию, потому что первое деление не является вхождением.
Тщательная проверка алгоритма
Необходимо протестировать метод на различных входных данных: строки разной длины, с разным числом совпадений, пустые строки, наличие подстроки в начале и в конце основной строки.
Размышления о производительности
Идеальный код – это компромисс между простотой, читаемостью и скоростью выполнения. Методы из Apache Commons Lang и использование регулярных выражений обычно удобнее, но они могут быть менее эффективны на больших строках или при сложных шаблонах.
Эффективность в сочетании с легкостью чтения
При проектировании алгоритма необходимо учитывать, что иногда встроенные методы обеспечивают оптимальное сочетание удобства чтения и эффективности, позволяя избежать излишне сложного кода.
Полезные материалы
- java – Количество вхождений подстроки в строку – Stack Overflow — Обсуждение различных решений.
- String (Java SE 11 & JDK 11 ) — Официальная документация по String API Java.
- Java – Регулярные выражения — Рекомендации по работе с классами Pattern и Matcher.
- Учебник | DigitalOcean — Анализ методов
indexOf()
иlastIndexOf()
. - java – Создание массива результатов регулярного выражения – Stack Overflow — Основы работы с регулярными выражениями в Java.
- Stream (Java Platform SE 8 ) — Документация Java Stream API.