Sorted List in Array Visual Basic [duplicate] - vb.net

This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 7 years ago.
I have a program that creates a list of 25 random numbers from 0 to 1,000. I have to buttons the first button will load a list box with the random numbers and the second button will sort the list of numbers from the smallest to largest which is where I implemented bubble sort code. Now the other list box that is supposed to hold the sorted numbers doesn't work properly it only shows one number instead of all of them.
Here is my code:
Option Strict On
Public Class Form1
Dim rn As Random = New Random
Dim Clicked As Long = 0
Dim numbers, sort As Long
Private Sub GenerateBtn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles GenerateBtn.Click
Clicked += 1
For x = 0 To 25
numbers = rn.Next(0, 1000)
RandomBox.Items.Add(numbers)
If Clicked >= 2 Then
RandomBox.Items.Clear()
Clicked = 1
End If
Next
End Sub
Private Sub SortBtn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SortBtn.Click
Dim Sorted() As Long = {numbers}
Dim Swapped As Boolean
Dim endOfArray As Integer = Sorted.Length - 1
Dim Tmp As Byte
While (Swapped)
Swapped = False
For I = 0 To endOfArray - 1
If Sorted(I) > Sorted(I + 1) Then
Tmp = CByte(Sorted(I))
Sorted(I) = Sorted(I + 1)
Sorted(I + 1) = Tmp
Swapped = True
End If
endOfArray = endOfArray - 1
Next
End While
SortBox.Items.Clear()
For I = 0 To Sorted.Count - 1
SortBox.Items.Add(Sorted(I))
Next
End Sub
End Class

Change your:
Dim Sorted() As Long = {numbers}
to
Sorted(x) = numbers
edit: Since you changed your code. You need to put back in the line that loads the Sorted Array.
For x = 0 To 25
numbers = rn.Next(0, 1000)
RandomBox.Items.Add(numbers)
Sorted(x) = numbers
If Clicked >= 2 Then
RandomBox.Items.Clear()
Clicked = 1
End If
Next
and remove the:
Dim Sorted() As Long = {numbers}
from the second part and put this declaration back in the beginning like you had:
Dim Sorted(26) as Long
The way you have will only show the latest random number. It is not any array but a single entity. Therefore only the latest will be add into the array. You need to load each number into the array as you create each one. Thus the (x) which loads it into position x.

You didn't use any arrays at all in your project...you're using the ListBox as your storage medium and that's a really bad practice.
I recommend you set it up like this instead:
Public Class Form1
Private rn As New Random
Private numbers(24) As Integer ' 0 to 24 = 25 length
Private Sub GenerateBtn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles GenerateBtn.Click
For x As Integer = 0 To numbers.Length - 1
numbers(x) = rn.Next(0, 1000)
Next
' reset the listbox datasource to view the random numbers
RandomBox.DataSource = Nothing
RandomBox.DataSource = numbers
' empty out the sorted listbox
SortBox.DataSource = Nothing
End Sub
Private Sub SortBtn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SortBtn.Click
' make a COPY of the original array that we will sort:
Dim sorted(numbers.Length - 1) As Integer
Array.Copy(numbers, sorted, numbers.Length)
Dim Swapped As Boolean = True
Dim endOfArray As Integer = Sorted.Length - 1
Dim Tmp As Integer
While (Swapped)
Swapped = False
For I As Integer = 0 To endOfArray - 1
If sorted(I) > sorted(I + 1) Then
Tmp = sorted(I)
sorted(I) = sorted(I + 1)
sorted(I + 1) = Tmp
Swapped = True
End If
Next
endOfArray = endOfArray - 1
End While
' reset the listbox datasource to view the sorted numbers
SortBox.DataSource = Nothing
SortBox.DataSource = sorted
End Sub
End Class
Also, note that you were decrementing endOfArray inside your for loop. You should only decrement it after each pass; so outside the for loop, but inside the while loop.
Additionally, you were using a Tmp variable of type Byte, but generating numbers between 0 and 999 (inclusive). The Byte type can only hold values between 0 and 255 (inclusive).
Your Bubble Sort implementation was very close to correct!

Related

Shell Sort Algorithm

I am attempting to implement an array using the shell sort algorithm. The program will sort the array and output each element to the Listbox after the button was clicked. However, the first item output is always 0. I have included a piece of my source code and a photo of the form below;
Dim randGen As New Random()
Dim unstArray() As Integer
Dim unstArrayCopy() As Integer
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 'Generates random number to save in array.
Dim i As Integer = CInt(TextBox1.Text)
ReDim unstArray(i)
ReDim unstArrayCopy(i)
For x = 0 To i
unstArray(x) = randGen.Next(1, 10001)
Next
Array.Copy(unstArray, unstArrayCopy, i)
End Sub
Private Sub ShllSrtBtn_Click(sender As Object, e As EventArgs) Handles shllSrtBtn.Click
shellsort(unstArrayCopy, unstArrayCopy.GetUpperBound(0))
End Sub
Sub shellsort(ByRef shellSort() As Integer, ByVal max As Integer)
Dim stopp%, swap%, limit%, temp%, k%
Dim x As Integer = CInt((max / 2) - 1)
Do While x > 0
stopp = 0
limit = max - x
Do While stopp = 0
swap = 0
For k = 0 To limit
If shellSort(k) > shellSort(k + x) Then
temp = shellSort(k)
shellSort(k) = shellSort(k + x)
shellSort(k + x) = temp
swap = k
End If
Next k
limit = swap - x
If swap = 0 Then stopp = 1
Loop
x = CInt(x / 2)
Loop
For i = 0 To shellSort.GetUpperBound(0)
ListBox1.Items.Add(shellSort(i))
Next i
End Sub
The problem is here:
ReDim unstArray(i)
ReDim unstArrayCopy(i)
In VB, when you initialize an array, you must give it the maximum index you want to use, not the intended array length as in other languages like C#.
Because of that, your code creates an array of length i+1, but you only loop from 0 to i when filling the array. So the last element at index i will always be zero.
You should set the initializer in these lines to i-1.
VB Array Reference

Lottery Program - Visual Basic

Have to create a lottery program, getting the random numbers and such easily enough. However I'm stumped. Essentially I have 2 buttons. One to display a checked list box with numbers 1-100, along with the 5 lotto numbers. I have a 2nd button that checks 2 things, to make sure that more than 5 numbers are not checked matching numbers. I'm lost on how to check for a match between the selected numbers between the RNG numbers.
Public Class Form1
Private Sub displayBtn_Click(sender As Object, e As EventArgs) Handles displayBtn.Click
Dim lottoNumbers(5) As Integer
Dim counter As Integer = 0
Dim number As Integer
Dim randomGenerator As New Random(Now.Millisecond)
'This will randomly select 5 unique numbers'
Do While counter < 5
number = randomGenerator.Next(0, 98)
If Array.IndexOf(lottoNumbers, number) = -1 Then
lottoNumbers(counter) = number
counter += 1
End If
Loop
'Display the lottery numbers in the label.'
Label1.Text = String.Empty
Array.Sort(lottoNumbers)
For Each num As Integer In lottoNumbers
Label2.Text = "Lottery Numbers"
Label1.Text &= CStr(num) & " "
Next num
For x = 0 To 98
CheckedListBox1.Items.Add(x + 1)
Next
End Sub
Private Sub checkBtn_Click(sender As Object, e As EventArgs) Handles checkBtn.Click
Dim count As Integer = 0
Dim x As Integer
'Checks to see if user checked more than 5'
For x = 0 To CheckedListBox1.Items.Count - 1
If (CheckedListBox1.CheckedItems.Count > 5) Then
MessageBox.Show("You cannot select more than 5 numbers.")
Return
Else
If (CheckedListBox1.GetItemChecked(x) = True) Then
count = count + 1
ListBox1.Items.Add(CheckedListBox1.Items(x))
End If
End If
Next
End Sub

Visual Basic: How can i display the prime numbers between 1 and the inputted number

Hello everyone so i'm trying to find the prime numbers of any input. I want them to be in a listbox and the input in a text box. I would like to use two arguments but i don't know how to. this is the code i have i need dire help. I am not the best at visual basic i just need some guidance. My code isn't working but display a drop down box when i press display.
Public Class Form1
Private Sub Button3_Click_1(sender As Object, e As EventArgs) Handles Button3.Click
Dim prim As Integer
Dim test As Integer
Dim imPrime As Boolean = False
prim = CInt(txtNum.Text)
test = prim
If prim = 1 Then
imPrime = False
MessageBox.Show("Enter a number greater than one please")
Else
Do While prim >= 2
For i As Integer = 2 To prim
If prim Mod i = 0 Then
imPrime = False
Exit For
Else
imPrime = True
lstPrime.Items.Add(prim)
End If
Next
Loop
End If
If imPrime = True Then
lstPrime.Items.Add(prim)
End If
End Sub
End Class
This is my fastest VBA code to generate prime numbers between two numbers.
The generated prime numbers are put in clipboard. You will need to open
your ms office word and type Ctrl+V to view all the generated prime numbers.
Sub generateprimenumbersbetween()
Dim starting_number As Long
Dim last_number As Long
Dim primenumbers As Variant
Dim a As Long
Dim b As Long
Dim c As Long
starting_number = 1 'input value here
last_number = 1000000 'input value here
primenumbers = ""
For a = starting_number To last_number
c = Round(Sqr(a)) + 1
For b = 2 To c
If a = 1 Or (a Mod b = 0 And c <> b) Then
Exit For
Else
If b = c Then
primenumbers = primenumbers & " " & a
Exit For
End If
End If
Next b
Next a
Dim answer As DataObject
Set answer = New DataObject
answer.SetText primenumbers
answer.PutInClipboard
End Sub
I think the while loop is not working as you intend. You need two loops, the first one counting up to the possible prime, and an inner one counting up to the counter in the outer loop.
You can find examples everywhere... here's one implemented in C#, but since your question was specifically about a listbox, I've translated it to VB.
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
calculatePrimes()
End Sub
Private Sub calculatePrimes()
Dim prim As Integer
Dim count As Integer = 0
prim = CInt(Me.TextBox1.Text)
If prim < 3 Then
MsgBox("Please enter a bigger number")
Return
End If
Me.ListBox1.Items.Clear()
For i As Integer = 1 To prim
Dim isPrime As Boolean = True
For j As Integer = 2 To i
If (i Mod j <> 0) Then count = count + 1
Next
If count = (i - 2) Then Me.ListBox1.Items.Add(i)
count = 0
Next
End Sub
End Class
(This assumes you have a textbox for input called TextBox1 and a listbox for display called ListBox1)

Visual Basic - Looping an array 100 times not working?

I'm trying to loop this array 100 times (gets a number from 0-99,999). I've tried it several different ways with no luck. I've got it set up so you click a button and it generates the array. The user will then enter a number and hit the other button to check how many times that number shows up in the group of a 100 numbers. Any thoughts how to fix it? I'm stuck.
Dim i As Integer
Dim rnd As New Random()
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnEnter.Click
Dim num As Integer
If Int32.TryParse(txtEnter.Text, num) AndAlso num >= 0 AndAlso num < 10 Then
lblNumber.Text = i.ToString()
Dim counts = From c In i.ToString()
Group By c Into Group
Select DigitGroup = New With {.Count = Group.Count(), .Digit = c, .Group = Group}
Order By DigitGroup.Count Descending, DigitGroup.Digit
Dim numCount = counts.FirstOrDefault(Function(grp) grp.Digit.ToString() = num.ToString())
If numCount IsNot Nothing Then
Dim numMessage = String.Format("There are {0} number {1}'s found.", numCount.Count, num)
MessageBox.Show(numMessage)
Else
MessageBox.Show("Your number does not contain a " & num)
End If
Else
MessageBox.Show("Please enter a number between 0 and 9.")
End If
End Sub
Private Sub btnGetNumber_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGetNumber.Click
btnEnter.Enabled = True
i = 0
Do Until i > 100
Dim randomInt = rnd.Next(0, 100000)
i = i + 1
i = rnd.Next(0, 100000)
Loop
End Sub
End Class
First of all, it is common to use For Loops when you know the number of loops.
Secondly, you forgot to increment i in the until loop
Finally, you don't need to redeclare rnd in every loop. Something like that sounds better to me :
Dim rnd As New Random()
For i = 1 To 100
Dim randomInt = rnd.Next( 0 , 100000 )
Next
Move the New Random() out of that loop. Make it global and create the instance just one time.
(The Random generator starts using a seed obtained from the current time. Declaring a Random variable inside a loop result in the same seed used again and again. This gives back the same number defeating the randomness of the function) It is like: http://xkcd.com/221/
See another explanation here
Of course, if you don't increment the variable i used to control the loop, you will loop forever
Dim i As Integer
Dim rnd As New Random()
.....
i = 0
Do Until i > 100
Dim randomInt = rnd.Next(0, 100000)
i = i + 1
Loop
Said that, now I can't get what are you trying to do here. There is no array to check and you do not use the value obtained from the Random generator, simply, your i variable exits with value 101.
Now I am just guessing what are your intentions, but perhaps you want just this?
i = rnd.Next(0, 100000)
This will give to the variable i a random number and your subsequent code checks how many, of the required digit, are present in i
I see that you are not adding the variable "i" to increment:
i = 1
Do Until i > 100
Dim rnd As New Random()
Dim randomInt = rnd.Next(0, 100000)
i+=1 'Increment value of i by 1, same as i = i + 1
Loop
The variable of "i" will always be 1 if not incremented. Check that and let me know if that solves the problem!

Bubble Sort logical error VB.NET

This program suppose to sort records(in arySort) in ascending order by last name(index 1 in aryTemp and aryTemp2) and place the result in the list box over the old, preloaded, unsorted records.
It sorts them strangely, I have to click multiple times the Ascending button to get the actual sort result that I suppose to get from clicking the button once.
Why doesn't it sort items with a single mouse click?
The source:
Public Class Form1
Dim FILE_NAME As String = "Students.txt"
Dim numberOfRecords As Integer 'total number of records
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
If System.IO.File.Exists(FILE_NAME) = True Then
Dim objReader As New System.IO.StreamReader(FILE_NAME)
Do While objReader.Peek() <> -1
lstBox.Items.Add(objReader.ReadLine)
numberOfRecords += 1
Loop
objReader.Close()
End If
End Sub
Private Sub btnAscending_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAscending.Click
'load all students into array
Dim arySort(numberOfRecords - 1) As String
Dim aryTemp() As String 'holds first record's last name
Dim aryTemp2() As String 'holds second record's last name
For i = 0 To numberOfRecords - 1
arySort(i) = lstBox.Items(i)
Next
Dim temp As String 'holds temporary record
Dim k As Integer
For i = 0 To arySort.Length - 2
aryTemp = Split(arySort(i), " ")
For k = i + 1 To arySort.Length - 1
aryTemp2 = Split(arySort(k), " ")
If aryTemp(1) < aryTemp2(1) Then
temp = arySort(k)
arySort(k) = arySort(i)
arySort(i) = temp
End If
Next
Next
lstBox.Items.Clear()
numberOfRecords = 0
For i = 0 To arySort.Length - 1
lstBox.Items.Add(arySort(i))
numberOfRecords += 1
Next
End Sub
End Class
If you just need to sort your list (as you say in the comment), don't implement your own sort mechanism but use the one of .NET:
' Define how we want to compare items '
Function compareByLastName(ByVal item1 As String, ByVal item2 As String) As Integer
Return String.Compare(item1.Split(" ")(1), item2.Split(" ")(1))
End Function
Private Sub btnAscending_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAscending.Click
' load all students into array '
Dim arySort(numberOfRecords - 1) As String
For i = 0 To numberOfRecords - 1
arySort(i) = lstBox.Items(i)
Next
' Use built-in .NET magic '
Array.Sort(arySort, AddressOf compareByLastName)
' Write the values back into your list box '
lstBox.Items.Clear()
numberOfRecords = 0
For i = 0 To arySort.Length - 1
lstBox.Items.Add(arySort(i))
numberOfRecords += 1
Next
End Sub
This uses the built-in quicksort algorithm of the .NET class library. Here's the documentation of the method we are using: Array.Sort(T(), Comparison(Of T)).
compare with my working bubble sort:
Public Sub BubbleSort(ByVal arr() As Integer)
Dim flag As Boolean = False
For i As Integer = 0 To arr.Length - 1
For j As Integer = 0 To arr.Length - 2 - i
If arr(j + 1) < arr(j) Then
flag = True
Dim temp As Integer = arr(j)
arr(j) = arr(j + 1)
arr(j + 1) = temp
End If
Next
If flag = False Then Return ' no swaps =>already sorted
Next
End Sub
I see a two major issues with your algorithm:
It's not bubble sort. Bubble sort swaps adjacent elements, i.e., it swaps i with i+1. You, on the other hand, swap some element i with the first j > i where name(i) < name(j). Maybe you should show us, in pseudo code, which algorithm you are actually trying to implement?
aryTemp contains element i and aryTemp2 contains some element j > i. Why do you swap the elements if aryTemp(1) < aryTemp2(1)? Isn't that already the correct order if you want your elements to be sorted ascending?