Вхождения подстроки в строку - PullRequest
110 голосов
/ 20 апреля 2009

Почему следующий алгоритм не останавливается для меня? (str - строка, которую я ищу, findStr - строка, которую я пытаюсь найти)

String str = "helloslkhellodjladfjhello";
String findStr = "hello";
int lastIndex = 0;
int count = 0;

while (lastIndex != -1) {
    lastIndex = str.indexOf(findStr,lastIndex);

    if( lastIndex != -1)
        count++;

    lastIndex += findStr.length();
}

System.out.println(count);

Ответы [ 24 ]

175 голосов
/ 21 апреля 2009

Как насчет использования StringUtils.countMatches от Apache Commons Lang?

String str = "helloslkhellodjladfjhello";
String findStr = "hello";

System.out.println(StringUtils.countMatches(str, findStr));

Это выводит:

3
111 голосов
/ 20 апреля 2009

Ваш lastIndex += findStr.length(); был помещен за скобки, вызывая бесконечный цикл (когда совпадений не было найдено, lastIndex всегда был findStr.length()).

Вот исправленная версия:

String str = "helloslkhellodjladfjhello";
String findStr = "hello";
int lastIndex = 0;
int count = 0;

while (lastIndex != -1) {

    lastIndex = str.indexOf(findStr, lastIndex);

    if (lastIndex != -1) {
        count++;
        lastIndex += findStr.length();
    }
}
System.out.println(count);
84 голосов
/ 21 апреля 2009

более короткая версия. ;)

String str = "helloslkhellodjladfjhello";
String findStr = "hello";
System.out.println(str.split(findStr, -1).length-1);
81 голосов
/ 20 апреля 2009

Последняя строка создала проблему. lastIndex никогда не будет в -1, поэтому будет бесконечный цикл. Это можно исправить, переместив последнюю строку кода в блок if.

String str = "helloslkhellodjladfjhello";
String findStr = "hello";
int lastIndex = 0;
int count = 0;

while(lastIndex != -1){

    lastIndex = str.indexOf(findStr,lastIndex);

    if(lastIndex != -1){
        count ++;
        lastIndex += findStr.length();
    }
}
System.out.println(count);
78 голосов
/ 20 апреля 2009

Вы действительно должны сами справиться с соответствием? Особенно, если все, что вам нужно, это количество вхождений, регулярные выражения более аккуратны:

String str = "helloslkhellodjladfjhello";
Pattern p = Pattern.compile("hello");
Matcher m = p.matcher(str);
int count = 0;
while (m.find()){
    count +=1;
}
System.out.println(count);     
9 голосов
/ 12 апреля 2015

Вот так, завернутый в хороший и многократно используемый метод:

public static int count(String text, String find) {
        int index = 0, count = 0, length = find.length();
        while( (index = text.indexOf(find, index)) != -1 ) {                
                index += length; count++;
        }
        return count;
}
8 голосов
/ 20 апреля 2009
String str = "helloslkhellodjladfjhello";
String findStr = "hello";
int lastIndex = 0;
int count = 0;

while((lastIndex = str.indexOf(findStr, lastIndex)) != -1) {
     count++;
     lastIndex += findStr.length() - 1;
}
System.out.println(count);

в конце счетчика цикла равно 3; надеюсь, это поможет

6 голосов
/ 30 июня 2017

Я очень удивлен, что никто не упомянул этот лайнер. Это просто, кратко и работает немного лучше, чем str.split(target, -1).length-1

public static int count(String str, String target) {
    return (str.length() - str.replace(target, "").length()) / target.length();
}
6 голосов
/ 04 августа 2017
public int countOfOccurrences(String str, String subStr) {
  return (str.length() - str.replaceAll(Pattern.quote(subStr), "").length()) / subStr.length();
}
5 голосов
/ 26 февраля 2016

Многие из приведенных ответов дают сбой на одном или нескольких из:

  • Узоры произвольной длины
  • Перекрывающиеся совпадения (например, подсчет "232" в "23232" или "aa" в "aaa")
  • метасимволы регулярного выражения

Вот что я написал:

static int countMatches(Pattern pattern, String string)
{
    Matcher matcher = pattern.matcher(string);

    int count = 0;
    int pos = 0;
    while (matcher.find(pos))
    {
        count++;
        pos = matcher.start() + 1;
    }

    return count;
}

Пример вызова:

Pattern pattern = Pattern.compile("232");
int count = countMatches(pattern, "23232"); // Returns 2

Если вам нужен поиск без регулярных выражений, просто скомпилируйте ваш шаблон соответствующим образом с флагом LITERAL:

Pattern pattern = Pattern.compile("1+1", Pattern.LITERAL);
int count = countMatches(pattern, "1+1+1"); // Returns 2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...