Occurrences of substring in a string

JavaString

Java Problem Overview


Why is the following algorithm not halting for me? (str is the string I am searching in, findStr is the string I am trying to find)

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

Java Solutions


Solution 1 - Java

How about using StringUtils.countMatches from Apache Commons Lang?

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

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

That outputs:

3

Solution 2 - Java

Your lastIndex += findStr.length(); was placed outside the brackets, causing an infinite loop (when no occurence was found, lastIndex was always to findStr.length()).

Here is the fixed 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);

Solution 3 - Java

A shorter version. ;)

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

Solution 4 - Java

The last line was creating a problem. lastIndex would never be at -1, so there would be an infinite loop. This can be fixed by moving the last line of code into the if block.

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

Solution 5 - Java

Do you really have to handle the matching yourself ? Especially if all you need is the number of occurences, regular expressions are tidier :

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

Solution 6 - Java

I'm very surprised no one has mentioned this one liner. It's simple, concise and performs slightly better than str.split(target, -1).length-1

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

Solution 7 - Java

Here it is, wrapped up in a nice and reusable method:

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

Solution 8 - Java

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

at the end of the loop count is 3; hope it helps

Solution 9 - Java

public int countOfOccurrences(String str, String subStr) {
  return (str.length() - str.replaceAll(Pattern.quote(subStr), "").length()) / subStr.length();
}

Solution 10 - Java

A lot of the given answers fail on one or more of:

  • Patterns of arbitrary length
  • Overlapping matches (such as counting "232" in "23232" or "aa" in "aaa")
  • Regular expression meta-characters

Here's what I wrote:

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

Example call:

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

If you want a non-regular-expression search, just compile your pattern appropriately with the LITERAL flag:

Pattern pattern = Pattern.compile("1+1", Pattern.LITERAL);
int count = countMatches(pattern, "1+1+1"); // Returns 2

Solution 11 - Java

You can number of occurrences using inbuilt library function:

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

Solution 12 - Java

Increment lastIndex whenever you look for next occurrence.

Otherwise it's always finding the first substring (at position 0).

Solution 13 - Java

public int indexOf(int ch,
                   int fromIndex)

Returns the index within this string of the first occurrence of the specified character, starting the search at the specified index.

So your lastindex value is always 0 and it always finds hello in the string.

Solution 14 - Java

The answer given as correct is no good for counting things like line returns and is far too verbose. Later answers are better but all can be achieved simply with

str.split(findStr).length

It does not drop trailing matches using the example in the question.

Solution 15 - Java

try adding lastIndex+=findStr.length() to the end of your loop, otherwise you will end up in an endless loop because once you found the substring, you are trying to find it again and again from the same last position.

Solution 16 - Java

Try this one. It replaces all the matches with a -.

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

And if you don't want to destroy your str you can create a new string with the same content:

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

After executing this block these will be your values:

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

Solution 17 - Java

Here is the advanced version for counting how many times the token occurred in a user entered string:

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

}

Solution 18 - Java

This below method show how many time substring repeat on ur whole string. Hope use full to you:-

    String searchPattern="aaa"; // search string
    String str="aaaaaababaaaaaa"; // whole string
	int searchLength = searchPattern.length(); 
	int totalLength = str.length(); 
	int k = 0;
	for (int i = 0; i < totalLength - searchLength + 1; i++) {
		String subStr = str.substring(i, searchLength + i);
		if (subStr.equals(searchPattern)) {
		   k++;
		}

	}

Solution 19 - Java

As @Mr_and_Mrs_D suggested:

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

Solution 20 - Java

Based on the existing answer(s) I'd like to add a "shorter" version without the 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

Solution 21 - Java

This solution prints the total number of occurrence of a given substring throughout the string, also includes the cases where overlapping matches do exist.

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

Solution 22 - Java

here is the other solution without using regexp/patterns/matchers or even not using 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);

Solution 23 - Java

If you need the index of each substring within the original string, you can do something with indexOf like this:

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

Solution 24 - Java

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;

}

Solution 25 - Java

ļ‘ Just a little more peachy answer

    public int countOccurrences(String str, String sub) {
        if (str == null || str.length() == 0 || sub == null || sub.length() == 0) return 0;
        int count = 0;
        int i = 0;
        while ((i = str.indexOf(sub, i)) != -1) {
            count++;
            i += sub.length();
        }
        return count;
    }

Solution 26 - Java

I was asked this question in an interview just now and I went completely blank. (Like always, I told myself that the moment the interview ends ill get the solution) which I did, 5 mins after the call ended :(

    int subCounter=0;
	int count =0;
	for(int i=0; i<str.length(); i++) {
		if((subCounter==0 && "a".equals(str.substring(i,i+1))) 
				|| (subCounter==1 && "b".equals(str.substring(i,i+1)))
				|| (subCounter==2 && "c".equals(str.substring(i,i+1)))) {
			++subCounter;
		}
		if(subCounter==3) {
			count = count+1;
			subCounter=0;
		}
	}
	System.out.println(count);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionbobcomView Question on Stackoverflow
Solution 1 - JavaA_MView Answer on Stackoverflow
Solution 2 - JavaOlivierView Answer on Stackoverflow
Solution 3 - JavaPeter LawreyView Answer on Stackoverflow
Solution 4 - JavacodebreachView Answer on Stackoverflow
Solution 5 - JavaJeanView Answer on Stackoverflow
Solution 6 - JavakmecppView Answer on Stackoverflow
Solution 7 - JavamjsView Answer on Stackoverflow
Solution 8 - JavadfaView Answer on Stackoverflow
Solution 9 - JavaMaksym OvsianikovView Answer on Stackoverflow
Solution 10 - JavabenkcView Answer on Stackoverflow
Solution 11 - JavaVictorView Answer on Stackoverflow
Solution 12 - JavaStanislav KniazevView Answer on Stackoverflow
Solution 13 - JavaBhushan BhangaleView Answer on Stackoverflow
Solution 14 - JavaMarkView Answer on Stackoverflow
Solution 15 - JavaThorsten SchleinzerView Answer on Stackoverflow
Solution 16 - JavaXanderView Answer on Stackoverflow
Solution 17 - JavaVenzentxView Answer on Stackoverflow
Solution 18 - JavadugguView Answer on Stackoverflow
Solution 19 - JavaRon TeslerView Answer on Stackoverflow
Solution 20 - JavasjkmView Answer on Stackoverflow
Solution 21 - JavaAnubhav SinghView Answer on Stackoverflow
Solution 22 - JavaArun Kumar MudraboyinaView Answer on Stackoverflow
Solution 23 - JavaRhinoView Answer on Stackoverflow
Solution 24 - JavaNikolai NechaiView Answer on Stackoverflow
Solution 25 - JavaucMediaView Answer on Stackoverflow
Solution 26 - JavaShahid SarwarView Answer on Stackoverflow