Pourquoi l’algorithme suivant ne s’arrête-t-il pas pour moi? (Str est la chaîne dans laquelle je cherche, findStr est la chaîne que je cherche)
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);
La dernière ligne créait un problème. lastIndex
ne serait jamais à -1, donc il y aurait une boucle infinie. Cela peut être corrigé en déplaçant la dernière ligne de code dans le bloc 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);
Que diriez-vous d'utiliser StringUtils.countMatches d'Apache Commons Lang?
String str = "helloslkhellodjladfjhello";
String findStr = "hello";
System.out.println(StringUtils.countMatches(str, findStr));
Cela génère:
3
Votre lastIndex += findStr.length();
a été placé en dehors des crochets, provoquant une boucle infinie (quand aucune occurrence n'a été trouvée, lastIndex était toujours à findStr.length()
).
Voici la version corrigée:
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);
Une version plus courte. ;)
String str = "helloslkhellodjladfjhello";
String findStr = "hello";
System.out.println(str.split(findStr, -1).length-1);
Devez-vous vraiment faire la correspondance vous-même? Surtout si vous n'avez besoin que du nombre d'occurrences, les expressions régulières sont plus ordonnées:
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);
Le voici, emballé dans une méthode agréable et réutilisable:
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;
}
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);
à la fin de la boucle, le nombre est 3; J'espère que ça aide
public int countOfOccurrences(String str, String subStr) {
return (str.length() - str.replaceAll(Pattern.quote(subStr), "").length()) / subStr.length();
}
Un grand nombre des réponses données échouent sur un ou plusieurs des problèmes suivants:
Voici ce que j'ai écrit:
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;
}
Exemple d'appel:
Pattern pattern = Pattern.compile("232");
int count = countMatches(pattern, "23232"); // Returns 2
Si vous souhaitez une recherche avec une expression non régulière, il vous suffit de compiler votre modèle de manière appropriée avec l'indicateur LITERAL
:
Pattern pattern = Pattern.compile("1+1", Pattern.LITERAL);
int count = countMatches(pattern, "1+1+1"); // Returns 2
Je suis très surpris que personne n'ait mentionné cette doublure. C'est simple, concis et fonctionne légèrement mieux que str.split(target, -1).length-1
public static int count(String str, String target) {
return (str.length() - str.replace(target, "").length()) / target.length();
}
Incrémentez lastIndex
chaque fois que vous recherchez l'occurrence suivante.
Sinon, on trouve toujours la première sous-chaîne (en position 0).
public int indexOf(int ch,
int fromIndex)
Retourne l'index dans cette chaîne de la première occurrence du caractère spécifié, démarrant la recherche à l'index spécifié.
Donc, votre valeur lastindex
est toujours 0 et il trouve toujours hello dans la chaîne.
Vous pouvez nombre d'occurrences en utilisant la fonction de bibliothèque intégrée:
import org.springframework.util.StringUtils;
StringUtils.countOccurrencesOf(result, "R-")
essayez d’ajouter 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 même position.
Essaye celui-là. Il remplace toutes les correspondances avec un -
.
String str = "helloslkhellodjladfjhello";
String 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:
String str = "helloslkhellodjladfjhello";
String strDestroy = str;
String 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 correcte n'est pas bonne pour compter des choses telles que les retours à la ligne et est beaucoup trop verbeuse. Les réponses ultérieures sont meilleures, mais tout peut être obtenu simplement avec
str.split(findStr).length
Il ne supprime pas les correspondances suivantes à l'aide de l'exemple de la question.
Comme @Mr_and_Mrs_D l'a suggéré:
String haystack = "hellolovelyworld";
String needle = "lo";
return haystack.split(Pattern.quote(needle), -1).length - 1;
Sur la base des réponses existantes, j'aimerais ajouter une version "plus courte" sans le if:
String str = "helloslkhellodjladfjhello";
String 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
voici l’autre solution sans utiliser regexp/patterns/matchers ni même avec StringUtils.
String str = "helloslkhellodjladfjhelloarunkumarhelloasdhelloaruhelloasrhello";
String findStr = "hello";
int count =0;
int findStrLength = findStr.length();
for(int i=0;i<str.length();i++){
if(findStr.startsWith(Character.toString(str.charAt(i)))){
if(str.substring(i).length() >= findStrLength){
if(str.substring(i, i+findStrLength).equals(findStr)){
count++;
}
}
}
}
System.out.println(count);
Cette solution imprime le nombre total d'occurrences d'une sous-chaîne donnée tout au long de la chaîne, ainsi que les cas où des correspondances se chevauchent.
class SubstringMatch{
public static void main(String []args){
//String str = "aaaaabaabdcaa";
//String sub = "aa";
//String str = "caaab";
//String sub = "aa";
String str="abababababaabb";
String 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 (m-n) position
while(index!=-1 && i<=(n-m)){
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);
}
}
La méthode ci-dessous montre combien de fois la sous-chaîne de temps est répétée sur toute la chaîne. J'espère utiliser plein pour vous: -
String search_pattern="aaa";
String 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++;
}
}
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<Integer> getAllIndexesOfSubstringInString(String fullString, String substring) {
int pointIndex = 0;
List<Integer> allOccurences = new ArrayList<Integer>();
while(fullPdfText.indexOf(substring,pointIndex) >= 0){
allOccurences.add(fullPdfText.indexOf(substring, pointIndex));
pointIndex = fullPdfText.indexOf(substring, pointIndex) + substring.length();
}
return allOccurences;
}
Voici la version avancée pour compter combien de fois le jeton s'est produit dans une chaîne entrée par l'utilisateur:
public class StringIndexOf {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter a sentence please: \n");
String string = scanner.nextLine();
int atIndex = 0;
int count = 0;
while (atIndex != -1)
{
atIndex = string.indexOf("hello", atIndex);
if(atIndex != -1)
{
count++;
atIndex += 5;
}
}
System.out.println(count);
}
}
public static int getCountSubString(String str , String 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;
}