Aidan McGinn Aidan McGinn - 6 months ago 17
Vb.net Question

Code is clean but when running it will not display

Public Class Form1

Private Sub GenerateAndSearch(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGenerate.Click, btnSearch.Click
Static intDataArray(-1) As Integer
Dim btnButtonClicked As Button = sender

Select Case btnButtonClicked.Tag
Case "Generate Array"
Call GenerateSortedArray(intDataArray)

Me.lstListArrayElements.Items.Clear()
Call DisplayData(intDataArray, Me.lstListArrayElements, "Sorted array:")

Case "Search Array"
Dim intNumToFind As Integer = Val(Me.txtNumToFind.Text)
Dim intNumFoundIndex As Integer

intNumFoundIndex = BinarySearch(intDataArray, intNumToFind)
If intNumFoundIndex = -1 Then
Me.lblFoundMessage.Text = "Number not found."
Else
Me.lblFoundMessage.Text = "Number found at index" & intNumFoundIndex
End If
End Select
End Sub

Sub GenerateSortedArray(ByRef intArray() As Integer)
Const intNUMELEMENTS As Integer = 50
Const intMAXNUMBER As Integer = 100
ReDim intArray(intNumElements - 1)

Randomize()
Dim intIndex As Integer
For intIndex = 0 To intArray.Length - 1
intArray(intIndex) = Int(intMAXNUMBER * Rnd()) + 1
Next intIndex
Call InsertionSort(intArray)
End Sub

Sub InsertionSort(ByRef intArray() As Integer)
Dim intIndex, intPreviousIndex, intTempItem As Integer

For intIndex = 1 To intArray.Length - 1
intTempItem = intArray(intIndex)
intPreviousIndex = intIndex - 1

Do While intPreviousIndex > 0 And
intArray(intPreviousIndex) > intTempItem
intArray(intPreviousIndex + 1) = intArray(intPreviousIndex)
intPreviousIndex = intPreviousIndex - 1
Loop

If intArray(intPreviousIndex) > intTempItem Then
intArray(intPreviousIndex + 1) = intArray(intPreviousIndex)
intArray(intPreviousIndex) = intTempItem
Else
intArray(intPreviousIndex + 1) = intTempItem
End If
Next intIndex
End Sub
Sub DisplayData(ByRef intArray() As Integer, ByRef lstList As ListBox, ByVal strTitle As String)
lstList.Items.Add(strTitle)
Dim intIndex As Integer
For intIndex = 0 To intArray.Length - 1
lstList.Items.Add(intIndex & vbTab & intArray(intIndex))
Next intIndex
End Sub

Function BinarySearch(ByRef intArray() As Integer, ByVal intNumToFind As Integer) As Integer
Dim intHighIndex As Integer = intArray.Length - 1
Dim intMidIndex As Integer
Dim intLowIndex As Integer = 0
Dim blnFound As Boolean = False

Do While (Not blnFound) And (intLowIndex <= intHighIndex)
intMidIndex = (intMidIndex + intLowIndex) / 2
If intArray(intMidIndex) = intNumToFind Then
blnFound = True
ElseIf intArray(intMidIndex) > intNumToFind Then
intHighIndex = intMidIndex - 1
Else
intLowIndex = intMidIndex + 1
End If
Loop
If blnFound Then
Return intMidIndex
Else
Return -1
End If
End Function
Private Sub NewData_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles txtNumtoFind.TextChanged, btnGenerate.Click
Me.lblFoundMessage.text = Nothing
End Sub
End Class


My problem is I cannot get my code to display a list of arrays to find. I cant see where im going wrong any ideas? Also my sort button is not working but that may be due to the fact nothing shows up when i click button
btnGenerate
.

Answer

Your biggest problem appears to be in your BinarySearch function. The reason you weren't getting any display is the BinarySearch function had an infinite loop. Here's some corrected code with explanations and is tested and working:

Function BinarySearch(ByRef intArray() As Integer, ByVal intNumToFind As Integer) As Integer
    Dim intHighIndex As Integer = intArray.Length - 1
    Dim intMidIndex As Integer
    Dim intLowIndex As Integer = 0
    Dim blnFound As Boolean = False

    Do While (Not blnFound) And (intLowIndex <= intHighIndex)
        'This should add high and low then divide by 2 not mid and low
        'Also you should use the integer division sign to return an integer result
        intMidIndex = (intHighIndex + intLowIndex) \ 2
        If intArray(intMidIndex) = intNumToFind Then
            blnFound = True
            'mid should become the new limit without any inc/decrement
        ElseIf intArray(intMidIndex) > intNumToFind Then
            intHighIndex = intMidIndex
        Else
            intLowIndex = intMidIndex
        End If
    Loop
    If blnFound Then
        Return intMidIndex
    Else
        Return -1
    End If
End Function

A couple of other corrections that should be made:

Select Case btnButtonClicked.Tag should be Select Case btnButtonClicked.Tag.ToString()

intArray(intIndex) = Int(intMAXNUMBER * Rnd()) + 1 should be intArray(intIndex) = CInt(intMAXNUMBER * Rnd()) + 1

One other thought, you might want to put a check in the generate routine to only generate unique numbers. Binary search will only find one element but not any of the others if there are more.