Ermitteln Sie die Anzahl der Vorkommen einer Teilzeichenfolge in einer Zeichenfolge

Lesezeit: 6 Minuten

Warum stoppt der folgende Algorithmus nicht für mich?

Im folgenden Code str ist die Zeichenfolge, in der ich suche, und findStr ist die Zeichenkette, die ich zu finden versuche.

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);

  • Wir haben in Udacity einen wirklich guten gemacht: wir haben newSTR = str.replace(findStr, “”); und zurückgegebene Anzahl = ((str.length() – newSTR.length())/findStr.length());

    – SolarLunix

    14. September 2015 um 17:46 Uhr

  • Ähnliche Frage für Zeichen: stackoverflow.com/q/275944/873282

    – koppor

    16. April 2017 um 19:42 Uhr

  • Wollen Sie nicht auch den Fall berücksichtigen, in dem das Präfix des Suchstrings sein Suffix ist? In diesem Fall glaube ich nicht, dass eine der vorgeschlagenen Antworten funktionieren würde. Hier ist ein Beispiel. In diesem Fall benötigen Sie einen ausgefeilteren Algorithmus, wie den Knuth Morris Pratt (KMP), der im CLRS-Buch kodiert ist

    – Sid

    25. Juli 2017 um 15:42 Uhr


  • es hält für Sie nicht an, denn nachdem Sie Ihre ‘Halt’-Bedingung erreicht haben (lastIndex == -1), setzen Sie es zurück, indem Sie den Wert von lastIndex erhöhen (lastIndex += findStr.length();)

    – Legna

    1. August 2017 um 22:30 Uhr

  • @Sid Wenn Sie dieses Verhalten wollten, könnten Sie lastIndex jedes Mal nur um 1 erhöhen, anstatt findStr.length. In meinem Fall muss ich zum Beispiel nur wissen, ob ein Zeichen übereinstimmt oder nicht, es macht mir nichts aus, mehrere Überschneidungen zu zählen. hängt also nur vom jeweiligen Anwendungsfall ab

    – Adam Burley

    30. Januar 2021 um 2:44 Uhr

Benutzeravatar von A_M
BIN

Wie wäre es mit verwenden StringUtils.countMatches von Apache Commons Lang?

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

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

Das gibt aus:

3

  • Egal wie richtig dieser Vorschlag ist, er kann nicht als Lösung akzeptiert werden, da er die Frage von OP nicht beantwortet

    – kommradHomer

    12. Juli 2014 um 11:36 Uhr

  • Ist das veraltet oder so … meine IDE erkennt es nicht

    – Vamsi Pavan Mahesh

    18. Juli 2014 um 16:30 Uhr

  • @VamsiPavanMahesh StringUtils ist eine Bibliothek von Apache Commons. Überprüfe hier : commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/…

    – Anup

    15. September 2015 um 11:33 Uhr

  • Diese Antwort ist eine Kopie der Antwort von Peter Lawrey einen Tag zuvor (siehe unten).

    – Zon

    14. März 2016 um 14:36 ​​Uhr

  • StringUtils hat nicht countMatches Methode.

    – kariertes Hemd

    10. Mai 2018 um 9:19 Uhr

Oliviers Benutzeravatar
Olivier

Dein lastIndex += findStr.length(); wurde außerhalb der Klammern platziert, was eine Endlosschleife verursachte (wenn kein Vorkommen gefunden wurde, war lastIndex immer to findStr.length()).

Hier die gefixte Version:

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);

  • Dies schlägt für die Zeichenfolge “aaa” und die Teilzeichenfolge “aa” fehl. Es wird 1 zurückgegeben, während die Zählung zwei ist. Die Indizes der Vorkommen sind [0,1]

    – Nico

    14. Oktober 2021 um 21:31 Uhr

  • @Niko Das korrekte Ergebnis hängt davon ab, ob überlappende Übereinstimmungen zulässig sind oder nicht.

    – Uneingeschränkt

    14. Mai um 16:36 Uhr

Benutzeravatar von Peter Lawrey
Peter Lawrey

Eine kürzere Version. 😉

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

  • return haystack.split(Pattern.quote(needle), -1).length - 1; wenn zum Beispiel needle=":)"

    – Herr_und_Frau_D

    16. Dezember 2012 um 16:01 Uhr

  • @lOranger Ohne die ,-1 Es werden nachlaufende Übereinstimmungen fallen gelassen.

    – Peter Lawrey

    28. Dezember 2012 um 12:02 Uhr

  • Aua, danke, gut zu wissen! Das wird mir beibringen, die kleinen Zeilen im Javadoc zu lesen …

    – Laurent Gregoire

    28. Dezember 2012 um 12:05 Uhr

  • Nett! Aber es enthält nur nicht überlappende Übereinstimmungen, oder? ZB wird das passende “aa” in “aaa” 1 zurückgeben, nicht 2? Natürlich ist das Einbeziehen von überlappenden oder nicht überlappenden Übereinstimmungen sowohl gültig als auch abhängig von Benutzeranforderungen (vielleicht ein Flag zur Anzeige von Zählüberschneidungen, ja/nein)?

    – Cornel Masson

    26. April 2013 um 9:24 Uhr


  • -1 .. versuchen Sie, dies auf “aaaa” und “aa” auszuführen. Die richtige Antwort ist 3, nicht 2.

    – Kalyanaraman Santhanam

    15. September 2014 um 6:06 Uhr

Benutzeravatar von codebreach
Codebruch

Die letzte Zeile verursachte ein Problem. lastIndex würde niemals -1 sein, also würde es eine Endlosschleife geben. Dies kann behoben werden, indem die letzte Codezeile in den if-Block verschoben wird.

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);

Benutzeravatar von Jeans
Jean

Müssen Sie sich wirklich selbst um das Matching kümmern? Besonders wenn Sie nur die Anzahl der Vorkommen benötigen, sind reguläre Ausdrücke aufgeräumter:

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);     

  • Dies findet KEINE Sonderzeichen, es wird 0 für die folgenden Zeichenfolgen finden: String str = "hel+loslkhel+lodjladfjhel+lo"; Pattern p = Pattern.compile("hel+lo");

    – Ben

    2. Februar 2014 um 4:09 Uhr


  • Ja, das wird es, wenn Sie Ihre Regex richtig ausdrücken. Versuche es mit Pattern.compile("hel\\+lo"); Die + sign hat in einer Regex eine besondere Bedeutung und muss maskiert werden.

    – Jean

    2. Februar 2014 um 9:42 Uhr

  • Wenn Sie nach einer beliebigen Zeichenfolge suchen und diese als exakte Übereinstimmung verwenden möchten, wobei alle Sonderzeichen für reguläre Ausdrücke ignoriert werden, Pattern.quote(str) ist dein Freund!

    – Mike Furtak

    10. Januar 2015 um 18:11 Uhr


  • dies funktioniert nicht für “aaa”, wenn str = “aaaaaa”. Es gibt 4 Antworten, aber deine gibt 2

    – Pujan

    29. Oktober 2016 um 12:02 Uhr

  • Diese Lösung funktioniert in diesem Fall nicht: str = “This is a test \\n\\r string”, subStr = “\\r”, es zeigt 0 Vorkommen.

    – Maksym Ovsianikov

    1. Dezember 2017 um 23:21 Uhr

Ich bin sehr überrascht, dass niemand diesen einen Liner erwähnt hat. Es ist einfach, prägnant und funktioniert etwas besser als str.split(target, -1).length-1

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

  • Dies findet KEINE Sonderzeichen, es wird 0 für die folgenden Zeichenfolgen finden: String str = "hel+loslkhel+lodjladfjhel+lo"; Pattern p = Pattern.compile("hel+lo");

    – Ben

    2. Februar 2014 um 4:09 Uhr


  • Ja, das wird es, wenn Sie Ihre Regex richtig ausdrücken. Versuche es mit Pattern.compile("hel\\+lo"); Die + sign hat in einer Regex eine besondere Bedeutung und muss maskiert werden.

    – Jean

    2. Februar 2014 um 9:42 Uhr

  • Wenn Sie nach einer beliebigen Zeichenfolge suchen und diese als exakte Übereinstimmung verwenden möchten, wobei alle Sonderzeichen für reguläre Ausdrücke ignoriert werden, Pattern.quote(str) ist dein Freund!

    – Mike Furtak

    10. Januar 2015 um 18:11 Uhr


  • dies funktioniert nicht für “aaa”, wenn str = “aaaaaa”. Es gibt 4 Antworten, aber deine gibt 2

    – Pujan

    29. Oktober 2016 um 12:02 Uhr

  • Diese Lösung funktioniert in diesem Fall nicht: str = “This is a test \\n\\r string”, subStr = “\\r”, es zeigt 0 Vorkommen.

    – Maksym Ovsianikov

    1. Dezember 2017 um 23:21 Uhr

Hier ist es, verpackt in einer schönen und wiederverwendbaren Methode:

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;
}

1436820cookie-checkErmitteln Sie die Anzahl der Vorkommen einer Teilzeichenfolge in einer Zeichenfolge

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy