Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Get the highest numbers

Posted on 1997-11-03
10
Medium Priority
?
252 Views
Last Modified: 2006-11-17
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
Comment
Question by:Gustav
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
  • 2
  • +3
10 Comments
 
LVL 5

Expert Comment

by:dirtdart
ID: 1439566
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
 

Expert Comment

by:jonclegg
ID: 1439567
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
 

Author Comment

by:Gustav
ID: 1439568
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
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 

Expert Comment

by:jonclegg
ID: 1439569
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
 
LVL 6

Expert Comment

by:alamo
ID: 1439570
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
 

Expert Comment

by:KMichael
ID: 1439571
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
 
LVL 6

Expert Comment

by:alamo
ID: 1439572
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
 
LVL 9

Expert Comment

by:cymbolic
ID: 1439573
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
 

Author Comment

by:Gustav
ID: 1439574
waiting for answer from alamo!
0
 
LVL 6

Accepted Solution

by:
alamo earned 1000 total points
ID: 1439575
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

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

There are many ways to remove duplicate entries in an SQL or Access database. Most make you temporarily insert an ID field, make a temp table and copy data back and forth, and/or are slow. Here is an easy way in VB6 using ADO to remove duplicate row…
If you have ever used Microsoft Word then you know that it has a good spell checker and it may have occurred to you that the ability to check spelling might be a nice piece of functionality to add to certain applications of yours. Well the code that…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…
Suggested Courses

715 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question