Как посчитать вхождения символа или подстроки
Короткий ответ
Для одного символа удобно отфильтровать поток chars():
void main() {
long count = "banana".chars().filter(c -> c == 'a').count();
IO.println(count);
}Результат:
3Подстрока
Подстроку ищите indexOf() в цикле, каждый раз сдвигая начало поиска:
int countOf(String text, String part) {
int count = 0;
int index = text.indexOf(part);
while (index != -1) {
count++;
index = text.indexOf(part, index + part.length());
}
return count;
}
void main() {
IO.println(countOf("the cat and the hat", "the"));
}Результат:
2Через длину строки
Короткий приём: удалить все вхождения и посмотреть, на сколько уменьшилась длина:
void main() {
String text = "a,b,c,d";
int commas = text.length() - text.replace(",", "").length();
IO.println(commas);
}Результат:
3Частота всех символов
Чтобы посчитать каждый символ, соберите их в Map через merge():
void main() {
var counts = new TreeMap<Character, Integer>();
for (char c : "hello".toCharArray()) {
counts.merge(c, 1, Integer::sum);
}
IO.println(counts);
}Результат:
{e=1, h=1, l=2, o=1}Частая ошибка
Сдвигать поиск на 1 вместо длины подстроки. Тогда перекрывающиеся вхождения считаются по нескольку раз:
void main() {
String text = "aaaa";
int count = 0;
for (int i = text.indexOf("aa"); i != -1; i = text.indexOf("aa", i + 1)) {
count++;
}
IO.println(count);
}Результат:
3Если нужны непересекающиеся вхождения, сдвигайте на part.length(), как в примере выше — тогда результат будет 2.
Функции из этого ответа
- String.chars() — Возвращает поток кодов символов строки.
- String.indexOf() — Находит позицию первого вхождения символа или подстроки.
- String.replace() — Заменяет все вхождения подстроки или символа на другую строку.
- String.length() — Возвращает количество символов в строке.