2

I have to String objects:

String first = "/Some object that has a loop in it object/";
String second = "object";

What I need to do is find how many times does the second object repeat in the first object, can you please show me how to do that?

Xeen
  • 6,955
  • 16
  • 60
  • 111

8 Answers8

3

Use this single line which utilizes regular expressions in the background:

String[] parts = first.split(second);

String second occurs (parts.length - 1) times in String first. That's all.

EDIT:

To prevent unwanted results that could occur in the case of String second might contain regex-specific characters, you can use Pattern.quote(second) when passing it to split() method, as one of the commentators suggested.

Juvanis
  • 25,802
  • 5
  • 69
  • 87
  • 2
    I would recommend using `Pattern.quote` in the split - who knows what's in the second `String`. – Boris the Spider Apr 09 '13 at 13:25
  • @bmorris591 can you give an example of my code's probable bug? – Juvanis Apr 09 '13 at 13:29
  • If the second string contains some regex, for example $ or ( or [, then the split will interpret the regex and return really odd things or maybe even throw an exception. – Boris the Spider Apr 09 '13 at 13:31
  • @bmorris591 thank you bro for enlightment. see my edit, please. – Juvanis Apr 09 '13 at 13:37
  • `split(re)` by default removes empty strings at the end of the array, which will cause this method to give wrong result. You need to use `split(re, -1)` to preserve them. – nhahtdh Jul 20 '15 at 07:29
1

The simplest way is to use indexOf in a loop, advancing the starting index each time that you find the word:

int ind = 0;
int cnt = 0;
while (true) {
    int pos = first.indexOf(second, ind);
    if (pos < 0) break;
    cnt++;
    ind = pos + 1; // Advance by second.length() to avoid self repetitions
}
System.out.println(cnt);

This will find the word multiple times if a word contains self-repetitions. See the comment above to avoid such "duplicate" finds.

Demo on ideone.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
1

Use regex, example:

import java.util.regex.*;

class Test {
    public static void main(String[] args) {
        String hello = "HelloxxxHelloxxxHello"; //String you want to 'examine'
        Pattern pattern = Pattern.compile("Hello"); //Pattern string you want to be matched
        Matcher  matcher = pattern.matcher(hello); 

        int count = 0;
        while (matcher.find())
            count++; //count any matched pattern

        System.out.println(count);    // prints how many pattern matched
    }
}

source: java regex match count

Community
  • 1
  • 1
oentoro
  • 740
  • 1
  • 11
  • 32
  • 1
    Make sure you quote the regex, who knows what's in the second `String`. – Boris the Spider Apr 09 '13 at 13:25
  • For input "ababab" this returns 1, while indexOf based solutions returns 2. – Betlista Sep 16 '14 at 15:24
  • @Betlista: Read the comment in the indexOf solution. `+1` finds overlapping matches. `+ needle.length()` finds non-overlapping matches. This method here finds non-overlapping matches – nhahtdh Jul 20 '15 at 07:31
0

Use this :

 String first = "/Some object that has a loop in it object/";
     String second = "object";
     Pattern pattern = Pattern.compile(second);
     Matcher matcher = pattern.matcher(first) ;
     long count = 0;
     while(matcher.find()) {
         count ++;

     }
     System.out.println(count);
Ankur Shanbhag
  • 7,746
  • 2
  • 28
  • 38
0

try like below...

String str = "/Some object that has a loop in it object/";
String findStr = "object";
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);
Pandian
  • 8,848
  • 2
  • 23
  • 33
0

You can either split the String on the second String and count the length of the resulting array, it will have one more element that that number of occurrences. Or you can use Pattern and Matcher, which is a slightly more proper approach.

public static void main(String[] args) throws UnsupportedEncodingException, IOException {
    String first = "/Some object that has a loop in it object/";
    String second = "object";

    System.out.println(first.split(Pattern.quote(second)).length - 1);

    final Pattern pattern = Pattern.compile(Pattern.quote(second));
    final Matcher matcher = pattern.matcher(first);
    int count = 0;
    while (matcher.find()) {
        count++;
    }

    System.out.println(count);

}

Don't forget to use Pattern.quote just in case.

Boris the Spider
  • 59,842
  • 6
  • 106
  • 166
0

I know this is an older topic, but off the top of my head, you could use recursion:

// Recursive routine to find the xth repeat of a string
public int atIndex(String searchin, String searchfor, int whichone, int pos) {
    return atIndex(searchin, searchfor, whichone, pos, 0);
}

public int atIndex(String searchin, String searchfor, int whichone, int pos, int recursed) {
    return (whichone>0?atIndex(searchin, searchfor, --whichone, searchin.indexOf(searchfor,pos)+1,++recursed):(recursed==0?-1:pos-1));
}

I'm new at Java, so there may be a speed or resources issue that I'm not aware of, but a little bit of testing should suss out any problems.

To call it, you might use:

    String HL7Test="MSH|^~\\&|EPIC|EPICADT|SMS|SMSADT|199912271408|CHARRIS|ADT^A04|1817457" ;
    System.out.println(atIndex(HL7Test, "|", 4, 0));

Hope this helps.

JWRIC
  • 1
  • The most precious resource in many programming languages is call stack. You can easily unfold this into a loop instead, which would make it more stable. Your code can hit, excuse the pun, a [stack overflow](https://en.wikipedia.org/wiki/Stack_overflow#Very_deep_recursion). – Xan Sep 16 '14 at 15:26
0

Here you only need two variables and do all the checking in the loop condition.

int pos = 0;
int count= 0;
while (first.indexOf(second, pos) >= 0) {
    count++;
    pos = first.indexOf(second, pos) + 1;
}

System.out.println(count);
dorc
  • 1
  • 2