107

We are given a string, say, "itiswhatitis" and a substring, say, "is". I need to find the index of 'i' when the string "is" occurs a second time in the original string.

String.indexOf("is") will return 2 in this case. I want the output to be 10 in this case.

10 Answers 10

228

Use overloaded version of indexOf(), which takes the starting index (fromIndex) as 2nd parameter:

str.indexOf("is", str.indexOf("is") + 1);
Sign up to request clarification or add additional context in comments.

1 Comment

This is ingenious.
64

I am using: Apache Commons Lang: StringUtils.ordinalIndexOf()

StringUtils.ordinalIndexOf("Java Language", "a", 2)

Comments

39
int first = string.indexOf("is");
int second = string.indexOf("is", first + 1);

This overload starts looking for the substring from the given index.

7 Comments

what if the occurence is more than twice?
Then nothing special happens, it will still take the second occurence.
what about the index of third occurence!
What about it? The question was to find the second occurence.
@PravatPanda: I guess you want to know how to get the third occurence? Then you could just continue the code in Jeroen's answer and add a third string.indexOf("is", second + 1); although it would probably be better to make a method that returns the Nth indexOf
|
1

You can write a function to return array of occurrence positions, Java has String.regionMatches function which is quite handy

public static ArrayList<Integer> occurrencesPos(String str, String substr) {
    final boolean ignoreCase = true;
    int substrLength = substr.length();
    int strLength = str.length();

    ArrayList<Integer> occurrenceArr = new ArrayList<Integer>();

    for(int i = 0; i < strLength - substrLength + 1; i++) {
        if(str.regionMatches(ignoreCase, i, substr, 0, substrLength))  {
            occurrenceArr.add(i);
        }
    }
    return occurrenceArr;
}

Comments

1

if you want to find index for more than 2 occurrence:

public static int ordinalIndexOf(String fullText,String subText,int pos){

    if(fullText.contains(subText)){
        if(pos <= 1){
            return fullText.indexOf(subText);
        }else{
            --pos;
            return fullText.indexOf(subText, ( ordinalIndexOf(fullText,subText,pos) + 1) );
        }
    }else{
        return -1;
    }

}

Comments

1

I hope I'm not late to the party.. Here is my answer. I like using Pattern/Matcher because it uses regex which should be more efficient. Yet, I think this answer could be enhanced:

    Matcher matcher = Pattern.compile("is").matcher("I think there is a smarter solution, isn't there?");
    int numOfOcurrences = 2;
    for(int i = 0; i < numOfOcurrences; i++) matcher.find();
    System.out.println("Index: " + matcher.start());

Comments

1

It seems to be a good party... I'm in:

public static int nthIndexOf(String str, String subStr, int count) {
    int ind = -1;
    while(count > 0) {
        ind = str.indexOf(subStr, ind + 1);
        if(ind == -1) return -1;
        count--;
    }
    return ind;
}

Comments

1

Anyone who is looking for Nth occurance of string

    public class NthOccuranceExample {
    
    public static void main(String[] args) {
        String str1 = "helloworld good morning good evening good night";
        String str2 = "ing";
        int n = 2;
    
        int index = nthOccurrence(str1, str2, n);
        System.out.println("index of str2 in str1 at occurrence "+ n +" = "+ index);
    }
    
    public static int nthOccurrence(String str1, String str2, int n) {
    
        String tempStr = str1;
        int tempIndex = -1;
        int finalIndex = 0;
        for(int occurrence = 0; occurrence < n ; ++occurrence){
            tempIndex = tempStr.indexOf(str2);
            if(tempIndex==-1){
                finalIndex = 0;
                break;
            }
            tempStr = tempStr.substring(++tempIndex);
            finalIndex+=tempIndex;
        }
        return --finalIndex;
    }
}

Comments

1

You can get any occurrence of a substring in a string with a recursive method like this without any libraries:

import java.util.Arrays;

public class Test {
    public static void main(String[] args) {
        String word = "unrestfulness";
        String[] temp = new String[word.length()];
        for (char c : word.toCharArray()) {
            int count = (int) Arrays.stream(temp).filter(e -> e != null && e.contains(String.valueOf(c))).count();
            int index = getIndex(word, String.valueOf(c), count);
            System.out.println(c + " " + count + " " + index);
            temp[index] = String.valueOf(c);
        }
    
        System.out.println("result -> " + Arrays.toString(temp));
    }
    
    public static int getIndex(String word, String letter, int count) {
        return count == 0 ? word.indexOf(letter) : word.indexOf(letter, getIndex(word, letter, count - 1) + 1);
    }
}

Comments

0

i think a loop can be used.

1 - check if the last index of substring is not the end of the main string.
2 - take a new substring from the last index of the substring to the last index of the main string and check if it contains the search string
3 - repeat the steps in a loop

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.