[Webinar] Streamline your web hosting managementRegister Today

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 255
  • Last Modified:

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!
0
Gustav
Asked:
Gustav
  • 3
  • 2
  • 2
  • +3
1 Solution
 
dirtdartCommented:
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.
0
 
joncleggCommented:
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(Numbers)) 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

0
 
GustavAuthor Commented:
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!
0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
joncleggCommented:
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.

0
 
alamoCommented:
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


0
 
KMichaelCommented:
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 );
}

0
 
alamoCommented:
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.
0
 
cymbolicCommented:
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!
0
 
GustavAuthor Commented:
waiting for answer from alamo!
0
 
alamoCommented:
Sorting the entire array is vast overkill, since you are throwing  away 99% of the results. Here's the 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

Thanks Gustav, glad i could help!
0

Featured Post

Receive 1:1 tech help

Solve your biggest tech problems alongside global tech experts with 1:1 help.

  • 3
  • 2
  • 2
  • +3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now