Occurrences de sous-chaîne dans une chaîne

Pourquoi l’algorithme suivant ne s’arrête pas pour moi? (str est la chaîne que je cherche, findStr est la chaîne que j’essaie de trouver)

Ssortingng str = "helloslkhellodjladfjhello"; Ssortingng 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); 

La dernière ligne créait un problème. lastIndex ne serait jamais à -1, il y aurait donc une boucle infinie. Cela peut être corrigé en déplaçant la dernière ligne de code dans le bloc if.

 Ssortingng str = "helloslkhellodjladfjhello"; Ssortingng 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); 

Que diriez-vous d’utiliser SsortingngUtils.countMatches d’Apache Commons Lang?

 Ssortingng str = "helloslkhellodjladfjhello"; Ssortingng findStr = "hello"; System.out.println(SsortingngUtils.countMatches(str, findStr)); 

Cela produit:

 3 

Votre dernier lastIndex += findStr.length(); a été placé en dehors des parenthèses, provoquant une boucle infinie (quand aucune occurrence n’a été trouvée, lastIndex a toujours été findStr.length() ).

Voici la version fixe:

 Ssortingng str = "helloslkhellodjladfjhello"; Ssortingng 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); 

Une version plus courte 😉

 Ssortingng str = "helloslkhellodjladfjhello"; Ssortingng findStr = "hello"; System.out.println(str.split(findStr, -1).length-1); 

Devez-vous vraiment gérer le jumelage vous-même? Surtout si tout ce dont vous avez besoin est le nombre d’occurrences, les expressions régulières sont plus ordonnées:

 Ssortingng str = "helloslkhellodjladfjhello"; Pattern p = Pattern.comstack("hello"); Matcher m = p.matcher(str); int count = 0; while (m.find()){ count +=1; } System.out.println(count); 
 Ssortingng str = "helloslkhellodjladfjhello"; Ssortingng findStr = "hello"; int lastIndex = 0; int count = 0; while((lastIndex = str.indexOf(findStr, lastIndex)) != -1) { count++; lastIndex += findStr.length() - 1; } System.out.println(count); 

à la fin du compte de la boucle est 3; J’espère que cela aide

Voilà, enveloppé dans une méthode agréable et réutilisable:

 public static int count(Ssortingng text, Ssortingng find) { int index = 0, count = 0, length = find.length(); while( (index = text.indexOf(find, index)) != -1 ) { index += length; count++; } return count; } 

Un grand nombre des réponses données échouent sur un ou plusieurs des éléments suivants:

  • Motifs de longueur arbitraire
  • Les correspondances superposées (par exemple, compter “232” dans “23232” ou “aa” dans “aaa”)
  • Méta-caractères d’expression régulière

Voici ce que j’ai écrit:

 static int countMatches(Pattern pattern, Ssortingng ssortingng) { Matcher matcher = pattern.matcher(ssortingng); int count = 0; int pos = 0; while (matcher.find(pos)) { count++; pos = matcher.start() + 1; } return count; } 

Exemple d’appel:

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

Si vous voulez une recherche non-régulière, comstackz simplement votre modèle avec l’indicateur LITERAL :

 Pattern pattern = Pattern.comstack("1+1", Pattern.LITERAL); int count = countMatches(pattern, "1+1+1"); // Returns 2 
 public int countOfOccurrences(Ssortingng str, Ssortingng subStr) { return (str.length() - str.replaceAll(Pattern.quote(subStr), "").length()) / subStr.length(); } 

Incrémente lastIndex chaque fois que tu lastIndex une prochaine occurrence.

Sinon, on trouve toujours la première sous-chaîne (à la position 0).

 public int indexOf(int ch, int fromIndex) 

Renvoie l’index dans cette chaîne de la première occurrence du caractère spécifié, en démarrant la recherche à l’index spécifié.

Donc, votre lastindex valeur d’ lastindex est toujours 0 et il trouve toujours un bonjour dans la chaîne.

Je ne peux pas croire que personne n’a mentionné ce seul paquebot. C’est simple, concis et fonctionne un peu mieux que str.split(target, -1).length-1

 public static int count(Ssortingng str, Ssortingng target) { return (str.length() - str.replace(target, "").length()) / target.length(); } 

Vous pouvez nombre d’occurrences en utilisant la fonction de bibliothèque intégrée:

 import org.springframework.util.SsortingngUtils; SsortingngUtils.countOccurrencesOf(result, "R-") 

essayez d’append lastIndex+=findStr.length() à la fin de votre boucle, sinon vous vous retrouverez dans une boucle sans fin car une fois que vous avez trouvé la sous-chaîne, vous essayez de la retrouver encore et encore à partir de la dernière position.

Essaye celui-là. Il remplace tous les matchs par un - .

 Ssortingng str = "helloslkhellodjladfjhello"; Ssortingng findStr = "hello"; int numberOfMatches = 0; while (str.contains(findStr)){ str = str.replaceFirst(findStr, "-"); numberOfMatches++; } 

Et si vous ne voulez pas détruire votre str vous pouvez créer une nouvelle chaîne avec le même contenu:

 Ssortingng str = "helloslkhellodjladfjhello"; Ssortingng strDestroy = str; Ssortingng findStr = "hello"; int numberOfMatches = 0; while (strDestroy.contains(findStr)){ strDestroy = strDestroy.replaceFirst(findStr, "-"); numberOfMatches++; } 

Après avoir exécuté ce bloc, ce seront vos valeurs:

 str = "helloslkhellodjladfjhello" strDestroy = "-slk-djladfj-" findStr = "hello" numberOfMatches = 3 

La réponse donnée comme étant correcte ne permet pas de compter des choses comme les retours de ligne et est beaucoup trop verbeux. Les réponses ultérieures sont meilleures mais tout peut être réalisé simplement avec

 str.split(findStr).length 

Il ne supprime pas les correspondances à l’aide de l’exemple de la question.

Comme @Mr_and_Mrs_D a suggéré:

 Ssortingng haystack = "hellolovelyworld"; Ssortingng needle = "lo"; return haystack.split(Pattern.quote(needle), -1).length - 1; 

Sur la base des réponses existantes, j’aimerais append une version “plus courte” sans le if:

 Ssortingng str = "helloslkhellodjladfjhello"; Ssortingng findStr = "hello"; int count = 0, lastIndex = 0; while((lastIndex = str.indexOf(findStr, lastIndex)) != -1) { lastIndex += findStr.length() - 1; count++; } System.out.println(count); // output: 3 

Cette méthode ci-dessous montre combien de sous-chaînes de temps se répètent sur votre chaîne entière. J’espère utiliser pleinement pour vous: –

  Ssortingng search_pattern="aaa"; Ssortingng whole_pattern=""aaaaaababaaaaaa; int j = search_pattern.length(); for (int i = 0; i < whole_pattern.length() - j + 1; i++) { String str1 = whole_pattern.substring(i, j + i); System.out.println("sub string loop " + i + " => " + str1); if (str1.equals(search_pattern)) { Constants.k++; } } 

voici l’autre solution sans utiliser regexp / patterns / matcher ou même sans utiliser SsortingngUtils.

 Ssortingng str = "helloslkhellodjladfjhelloarunkumarhelloasdhelloaruhelloasrhello"; Ssortingng findStr = "hello"; int count =0; int findStrLength = findStr.length(); for(int i=0;i= findStrLength){ if(str.subssortingng(i, i+findStrLength).equals(findStr)){ count++; } } } } System.out.println(count); 

Si vous avez besoin de l’index de chaque sous-chaîne dans la chaîne d’origine, vous pouvez faire quelque chose avec indexOf comme ceci:

  private static List getAllIndexesOfSubssortingngInSsortingng(Ssortingng fullSsortingng, Ssortingng subssortingng) { int pointIndex = 0; List allOccurences = new ArrayList(); while(fullPdfText.indexOf(subssortingng,pointIndex) >= 0){ allOccurences.add(fullPdfText.indexOf(subssortingng, pointIndex)); pointIndex = fullPdfText.indexOf(subssortingng, pointIndex) + subssortingng.length(); } return allOccurences; } 

Voici la version avancée permettant de compter le nombre de fois où le jeton est apparu dans une chaîne saisie par un utilisateur:

 public class SsortingngIndexOf { public static void main(Ssortingng[] args) { Scanner scanner = new Scanner(System.in); System.out.println("Enter a sentence please: \n"); Ssortingng ssortingng = scanner.nextLine(); int atIndex = 0; int count = 0; while (atIndex != -1) { atIndex = ssortingng.indexOf("hello", atIndex); if(atIndex != -1) { count++; atIndex += 5; } } System.out.println(count); } } 
 public static int getCountSubSsortingng(Ssortingng str , Ssortingng sub){ int n = 0, m = 0, counter = 0, counterSub = 0; while(n < str.length()){ counter = 0; m = 0; while(m < sub.length() && str.charAt(n) == sub.charAt(m)){ counter++; m++; n++; } if (counter == sub.length()){ counterSub++; continue; } else if(counter > 0){ continue; } n++; } return counterSub; 

}

Cette solution imprime le nombre total d’occurrences d’une sous-chaîne donnée dans la chaîne, y compris les cas où des correspondances se chevauchent.

 class SubssortingngMatch{ public static void main(Ssortingng []args){ //Ssortingng str = "aaaaabaabdcaa"; //Ssortingng sub = "aa"; //Ssortingng str = "caaab"; //Ssortingng sub = "aa"; Ssortingng str="abababababaabb"; Ssortingng sub = "bab"; int n = str.length(); int m = sub.length(); // index=-1 in case of no match, otherwise >=0(first match position) int index=str.indexOf(sub), i=index+1, count=(index>=0)?1:0; System.out.println(i+" "+index+" "+count); // i will traverse up to only (mn) position while(index!=-1 && i< =(nm)){ index=str.substring(i, n).indexOf(sub); count=(index>=0)?count+1:count; i=i+index+1; System.out.println(i+" "+index); } System.out.println("count: "+count); } 

}