Gustav
asked on
Get the highest numbers
This is the problem:
I have a variable 'Numbers(999) as byte' and I want to make the ten highest of these get into one label(1-10) each.
I know that I can compare each number to all the others, but tthat is about 1000000 operations, and this is quite slow in Visual Basic, so I'd be glad to get help with a faster way!
Thanx in advance!
I have a variable 'Numbers(999) as byte' and I want to make the ten highest of these get into one label(1-10) each.
I know that I can compare each number to all the others, but tthat is about 1000000 operations, and this is quite slow in Visual Basic, so I'd be glad to get help with a faster way!
Thanx in advance!
One possible solution would be to make a small database with a table just to hold the numbers. Then pull them out with a 'SORT ASCENDING' SQL statement.
Sort your array with a shellsort, an array of 1000 should take less then a second.
Private sub getHigh(Numbers() as integer, tenHigh() as integer)
Dim tempOrderArray() as integer
Dim I as integer
Redim tempOrderArray(ubound(Numb ers)) as integer
' sort your array
IntShellSort Numbers, tempOrderArray
' get the 10 highest into tenHigh
For I = 1 to 10
TenHigh(I) = Numbers(tempOrderArray(I))
Next
End sub
Public Sub IntShellSort(v() As Long, OrderArray() As Integer)
Dim i As Integer
Dim j As Integer
Dim gap As Integer
Dim ArraySize As Integer
Dim Temp As Long
ArraySize = UBound(v)
gap = ArraySize
Do
' if that was the last pass then break
If gap = 1 Then Exit Do
gap = gap / 2
For i = gap To ArraySize
For j = i - gap To 1 Step -gap
If v(OrderArray(j)) < v(OrderArray(j + gap)) Then Exit For
Temp = OrderArray(j)
OrderArray(j) = OrderArray(j + gap)
OrderArray(j + gap) = Temp
Next
Next
Loop
End Sub
Private sub getHigh(Numbers() as integer, tenHigh() as integer)
Dim tempOrderArray() as integer
Dim I as integer
Redim tempOrderArray(ubound(Numb
' sort your array
IntShellSort Numbers, tempOrderArray
' get the 10 highest into tenHigh
For I = 1 to 10
TenHigh(I) = Numbers(tempOrderArray(I))
Next
End sub
Public Sub IntShellSort(v() As Long, OrderArray() As Integer)
Dim i As Integer
Dim j As Integer
Dim gap As Integer
Dim ArraySize As Integer
Dim Temp As Long
ArraySize = UBound(v)
gap = ArraySize
Do
' if that was the last pass then break
If gap = 1 Then Exit Do
gap = gap / 2
For i = gap To ArraySize
For j = i - gap To 1 Step -gap
If v(OrderArray(j)) < v(OrderArray(j + gap)) Then Exit For
Temp = OrderArray(j)
OrderArray(j) = OrderArray(j + gap)
OrderArray(j + gap) = Temp
Next
Next
Loop
End Sub
ASKER
Your code seams quite good, but there are som problems.
1. It takes about 10 s and note below 1 that you told me!
2. It does only put zeros in the tenHigh variable!
3. My wonder: why use integer in two places and a long in the third for the same variable, in my version of visual basic that is impossible. I don't know about yours.
If you could correct these problems, I would be happy!
1. It takes about 10 s and note below 1 that you told me!
2. It does only put zeros in the tenHigh variable!
3. My wonder: why use integer in two places and a long in the third for the same variable, in my version of visual basic that is impossible. I don't know about yours.
If you could correct these problems, I would be happy!
Sorry I didn't even try out my code, your right it does take longer then I thought. Also I forgot a part of it. You'll need this before it's passed to the shellsort. Also the long/integer thing was also a mistake, my bad.
For i = 1 To UBound(numbers)
tempOrderArray(i) = i
Next
You'll be hard pressed to get the sort much faster with VB, the only other things I can suggest is using Jet or using a QuickSort.
For i = 1 To UBound(numbers)
tempOrderArray(i) = i
Next
You'll be hard pressed to get the sort much faster with VB, the only other things I can suggest is using Jet or using a QuickSort.
Sorting the entire array is vast overkill, since you are throwing away 99% of the results. Here's some code.
Dim TopTen(10) as Integer
For i = 1 To UBound(numbers)
if numbers(i) > TopTen(10) then
for j = 9 to 1 step -1 ' insert the new number into the topten array
if numbers(i) <= TopTen(j) then exit for
TopTen(j+1) = TopTen(j)
next
TopTen(j+1)=numbers(i)
end if
next
Dim TopTen(10) as Integer
For i = 1 To UBound(numbers)
if numbers(i) > TopTen(10) then
for j = 9 to 1 step -1 ' insert the new number into the topten array
if numbers(i) <= TopTen(j) then exit for
TopTen(j+1) = TopTen(j)
next
TopTen(j+1)=numbers(i)
end if
next
You can bilding DLL with function
void qsort( void *base, size_t num, size_t width, int (__cdecl *compare )(const void *elem1, const void *elem2 ) );
This function is very faster o(N*logN)
/* QSORT.C: This program reads the command-line
* parameters and uses qsort to sort them. It
* then displays the sorted arguments.
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
int compare( const void *arg1, const void *arg2 );
void main( int argc, char **argv )
{
int i;
/* Eliminate argv[0] from sort: */
argv++;
argc--;
/* Sort remaining args using Quicksort algorithm: */
qsort( (void *)argv, (size_t)argc, sizeof( char * ), compare );
/* Output sorted list: */
for( i = 0; i < argc; ++i )
printf( "%s ", argv[i] );
printf( "\n" );
}
int compare( const void *arg1, const void *arg2 )
{
/* Compare all of both strings: */
return _stricmp( * ( char** ) arg1, * ( char** ) arg2 );
}
void qsort( void *base, size_t num, size_t width, int (__cdecl *compare )(const void *elem1, const void *elem2 ) );
This function is very faster o(N*logN)
/* QSORT.C: This program reads the command-line
* parameters and uses qsort to sort them. It
* then displays the sorted arguments.
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
int compare( const void *arg1, const void *arg2 );
void main( int argc, char **argv )
{
int i;
/* Eliminate argv[0] from sort: */
argv++;
argc--;
/* Sort remaining args using Quicksort algorithm: */
qsort( (void *)argv, (size_t)argc, sizeof( char * ), compare );
/* Output sorted list: */
for( i = 0; i < argc; ++i )
printf( "%s ", argv[i] );
printf( "\n" );
}
int compare( const void *arg1, const void *arg2 )
{
/* Compare all of both strings: */
return _stricmp( * ( char** ) arg1, * ( char** ) arg2 );
}
No matter how much faster a sort you get, my approach is better because it's the right algorithm for the job. It runs in 1/10 the time or less, is 10 lines instead of 25, and is a lot simpler. Can't beat that.
I did some benchmarks. On an array of 1000 numbers my approach was less than 1/10 the time and had to do about 1/15 the number of comparisons (1,300 vs. 19,000). (This is with a maximum value to be sorted of 255, the max value makes a big difference, higher is quicker).
By the way, saying "it should take less than a second" ignores the fact that you don't know what kind of machine the other person has. On my work machine (PP200) the shellsort method took 1/10 of a second, my method 1/100. I increased the array size to 30,000 numbers and the new times were 19 seconds and 1/20 of a second.
I did some benchmarks. On an array of 1000 numbers my approach was less than 1/10 the time and had to do about 1/15 the number of comparisons (1,300 vs. 19,000). (This is with a maximum value to be sorted of 255, the max value makes a big difference, higher is quicker).
By the way, saying "it should take less than a second" ignores the fact that you don't know what kind of machine the other person has. On my work machine (PP200) the shellsort method took 1/10 of a second, my method 1/100. I increased the array size to 30,000 numbers and the new times were 19 seconds and 1/20 of a second.
Remember the Alamo. His algorithm is a one step through the array and can't be beat! Reject your answer, let Alamo answer, and give him the points!
ASKER
waiting for answer from alamo!
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.