views:

211

answers:

6

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.

+1  A: 

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.

Daniel Earwicker
+1  A: 

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
Dustin Campbell
It's subtle, but I believe this will have incorrect behavior on a string with a single 'a' in it.
Daniel LeCheminant
true that, thank you anyways.
tmhai
A: 

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)
Alex Cahill
A: 

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

Mark Brackett
+2  A: 

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
Daniel LeCheminant
A: 
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
dbasnett