Index of x Recurring Character
Question
The following code is supposed to show in a message box the index of the third a in the string checkme, but when I run the program it doesn't give me the right answer (should be 12, instead I get 9). What am I doing wrong and how would I go about making it work?
Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
Dim checkme As String = "thais is a sample sentence a"
Dim indexnum As Integer
indexnum = checkme.IndexOf("a", checkme.IndexOf("a") + 3)
MessageBox.Show(CStr(indexnum))
End Sub
Option Explicit and Strict must be On. Thanks in advance.
Solution
You're only finding the second "a". Try using a loop like so.
Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
Dim checkme As String = "thais is a sample sentence a"
Dim indexnum As Integer = -1
For i As Integer = 1 To 3
indexnum = checkme.IndexOf("a", indexnum + 1)
Next
MessageBox.Show(CStr(indexnum))
End Sub
OTHER TIPS
What am I doing wrong?
You're finding the second a
. I'm guessing you were thinking of this:
checkme.IndexOf("a", checkme.IndexOf("a", 3))
which would actually give you the right result. (It says "Find the first a that occurs after the first a that occurs on or after the 3rd character (which happens to be an a)")
Your original code said "Find the first a which occurs on or after 3 positions beyond the first a", which only gets you to the second a
.
How do I fix it?
You could just use the IndexOf
in a loop, reusing the last found index as the next start index.
Shared Public Function FindIndexOfNthChar(ByVal checkme as String, _
ByVal checkChar as Char, _
ByVal n as Integer) as Integer
Dim lastIndex As Integer = -1
For i As Integer = 1 To n
lastIndex = checkme.IndexOf(checkChar, lastIndex + 1)
If lastIndex = -1 Then Return -1
Next i
Return lastIndex
End Function
You have to be careful; if you don't check for -1
on every attempt and exit immediately, you can end up with wrong results.
If you forgot this (as some of the other posts seem to have), then if you search for the third a
in a string with a single a
you'll actually return the index of the first a
(When you try to find the second a, you'll reset your index to -1
, which essentially starts the search over)
For that reason, it might be clearer just to write exactly what you mean:
Shared Public Function FindIndexOfNthChar(ByVal checkme as String, _
ByVal checkChar as Char, _
ByVal n as Integer) as Integer
Dim count as Integer = 0
For i as Integer = 0 To checkme.Length - 1
If(checkme(i) = checkChar) Then
count += 1
If(count = n) Then Return i
End If
Next i
return -1
End Function
checkme.IndexOf("a")
is 2. Adding 3 gives 5. So the whole expression becomes:
indexnum = checkme.IndexOf("a", 5)
Which finds the second one.
If you want to find the Nth one, loop N times, and each time round the loop do:
pos = checkme.IndexOf('a', pos + 1)
Before the loop, set pos to be -1.
The code you have will not produce the desired effect. What it is instead doing is finding the first "a" which is at position 2. then it is finding the first "a" that occurs after position 5 (2+3). If you want the third "a" you could use something similar to the following
indexnum = checkme.IndexOf("a")
indexnum = checkme.IndexOf("a", indexnum+1)
indexnum = checkme.IndexOf("a", indexnum+1)
Why would it be 12? The next "a" after position 5 is at position 9. Your code basically breaks down to:
'thais is a sample...
'0123456789
Dim idxFirstA = checkme.IndexOf("a") ' equals 2
'thais is a sample...
'0123456789
Dim idxThirdA = checkme.IndexOf("a", 2 + 3) ' equals 9
You skip the 1st "a" (position 2), and then find the 2nd "a" (position 9).
Private Sub Button4_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles Button4.Click
Dim checkme As String = "thais is a sample sentence a"
Dim indexnum As Integer = -1, occrnc As Integer = 0
For x As Integer = 0 To checkme.Length - 1
indexnum = checkme.IndexOf("a", indexnum + 1)
If indexnum <> -1 Then occrnc += 1
If occrnc = 3 Then Exit For
Next
If occrnc = 3 Then MessageBox.Show(indexnum.ToString)
End Sub