1

I have one string

var inp = "ABCABCABC";

To get second occurrence of "A" am doing below

int index = inp.indexOf("A", inp.indexOf("A")+1);

But if I need third occurrence of "A", Why I cant do like this ?

int index = inp.indexOf("A", inp.indexOf("A")+2); ---Not Working  WHY....?

But this is

int index = inp.indexOf("A", inp.indexOf("A", inp.indexOf("A")+1)+1); --- Working 

Any suggestions ?

Andrea
  • 109
  • 2
  • 10
  • seeing as you don't return the index, just the place in the String, this might lead to wrong information( who says there is a +1 index?) You can use a combination of substring and indexOf to solve this quite easily – Stultuske Sep 24 '18 at 06:26
  • 2
    Read the JavaDoc of [String.indexOf](https://docs.oracle.com/javase/10/docs/api/java/lang/String.html#indexOf(java.lang.String)) to learn what this method returns. – LuCio Sep 24 '18 at 06:28
  • "Why I cant do like this ?" Because that's not logically how `indexOf` works. – Andy Turner Sep 24 '18 at 06:28
  • Gotta say, this is completely spelled out in the docs. Please read them. – Mad Physicist Sep 24 '18 at 06:29
  • indexOf("A") is 0. So indexOf("A")+2 is 2. So you're asking for the index of "A", starting from index 2. And the first index of "A" starting from index 2 is 3. – JB Nizet Sep 24 '18 at 06:29
  • Hey could you explain your problem i think you want something with X solve but you try it with Y. If you explain we can answer with X – Munkhdelger Tumenbayar Sep 24 '18 at 06:30
  • 1
    I think a better question is why you think you _can_ do that? Take a piece of paper and figure out what the code does, you'll quickly see that your suggestion doesn't follow the logic of `indexOf`. – Boris the Spider Sep 24 '18 at 06:30

2 Answers2

4

In this case, +1 just adds 1, nothing more. It doesn't skip n occurrences.

What I suggest you do is use a loop.

public static int findNth(String text, String find, int nth) {
    int last = -1;
    for (int i = 0; i < nth; i++) {
        last = text.indexOf(find, last + 1);
        if (last == -1) return -1;
    }
    return last;
}

You should be able to see this in your debugger however in you situation you have

int index = inp.indexOf("A", inp.indexOf("A")+1);

Which is the same as

int index = inp.indexOf("A", 0+1);

or

int index = inp.indexOf("A", 1);

as 0 + 1 == 1

If you change the code to

int index = inp.indexOf("A", inp.indexOf("A")+2);

You get

int index = inp.indexOf("A", 0+2);

which will only work if there is AA

This line

int index = inp.indexOf("A", inp.indexOf("A", inp.indexOf("A")+1)+1);

evaluates to

int index = inp.indexOf("A", inp.indexOf("A", 0+1)+1);

or

int index = inp.indexOf("A", 3+1);

or

int index = inp.indexOf("A", 4);
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
0

This only works because

int index = inp.indexOf("A");

returns the index of the first occurrence of A, beginning with the 0th character (inclusive). (See the documentation here.) If you set a second argument

int index = inp.indexOf("A", 5);

indexOf will only return the first A that it finds at or after index 5.


What you are doing is

int index = inp.indexOf("A", inp.indexOf("A")+1);

...which finds the first occurrence of "A", then moves to the next character in the String, then looks for the second occurrence of "A". This will only work if there are multiple "A" in the String.

Suppose you have a String like

String phil = "ABACAB";`

Then phil.indexOf("A") returns 0, and phil.indexOf("A", phil.indexOf("A")+1) simplifies to phil.indexOf("A", 0+1) or just phil.indexOf("A", 1). So you're looking for the first occurrence of "A" at or after the 1st index (the first "B" in "ABACAB"). This will return 2.

Doing something like:

int index = inp.indexOf("A", inp.indexOf("A")+2);

Does the same thing, but moves forward two characters, after finding the first occurrence of "A". So for our example, this simplifies to phil.indexOf("A", 2), which will return 2, finding the same, second "A" that it found in the first case.

To find the third occurrence, you need to chain the calls, as you noted:

int index = inp.indexOf("A", inp.indexOf("A", inp.indexOf("A")+1)+1);

Or use a third-party library.

awwsmm
  • 1,353
  • 1
  • 18
  • 28