Solved

sorting an array of strings

Posted on 2000-05-12
19
153 Views
Last Modified: 2010-05-02
im trying to write a hi score table for my quiz program, how do i sort the strings in decending order higest string first?

sample data might be

"0 Player  gerry Winnings £  100 Time Taken 0"

"4 Player  gerry Winnings £  500 Time Taken 46"

"0 Player  gerry Winnings £  100 Time Taken 0"

"0 Player  gerry Winnings £  100 Time Taken 15"

0
Comment
Question by:gerrymcd
  • 5
  • 5
  • 4
  • +3
19 Comments
 
LVL 9

Accepted Solution

by:
GivenRandy earned 50 total points
ID: 2805749
Option Explicit

Private Sub Command1_Click()
    Dim MyArray
    MyArray = Array("A", "Z", "M")
    Call SortDecending(MyArray)
    Debug.Print MyArray(0); MyArray(1); MyArray(2)
End Sub

Private Function SortDecending(a)
    Dim i, j As Long
    Dim tmp
    For i = 1 To UBound(a)
        For j = 0 To UBound(a)
            If LCase(a(i)) > LCase(a(j)) Then
                temp = a(j)
                a(j) = a(i)
                a(i) = temp
            End If
        Next
    Next
    SortDecending = a
End Function

0
 
LVL 9

Expert Comment

by:GivenRandy
ID: 2805756
You can also use QuickSort for large sets of data:

From Microsoft:

' ============================ QuickSort ============================
' QuickSort works by picking a random "pivot" element in SortArray,
' then moving every element that is bigger to one side of the pivot,
' & every element that is smaller to the other side. QuickSort is
' then called recursively with the two subdivisions created by the
' pivot. Once the number of elements in a subdivision reaches two,
' the recursive calls end and the array is sorted.
' ===================================================================
'
Private Sub QuickSort(SortArray() As String, ByVal Low As Long, _
                   ByVal High As Long)
   Dim I As Long, J As Long, RandIndex As Long, Partition As String
   If Low < High Then
      ' Only two elements in this subdivision; swap them if they are
      ' out of order, then end recursive calls:
      If High - Low = 1 Then
         If UCase(SortArray(Low)) > UCase(SortArray(High)) Then
            SWAP SortArray(Low), SortArray(High)
         End If
      Else
         ' Pick a pivot element at random, then move it to the end:
         RandIndex = Rnd() * (High - Low) + Low ' RandInt%(Low, High)
         SWAP SortArray(High), SortArray(RandIndex)
         Partition = UCase(SortArray(High))
         Do
            ' Move in from both sides towards the pivot element:
            I = Low: J = High
            Do While (I < J) And (UCase(SortArray(I)) <= Partition)
               I = I + 1
            Loop
            Do While (J > I) And (UCase(SortArray(J)) >= Partition)
               J = J - 1
            Loop

            ' If we haven't reached the pivot element it means that 2
            ' elements on either side are out of order, so swap them:
            If I < J Then
               SWAP SortArray(I), SortArray(J)
            End If
         Loop While I < J

         ' Move the pivot element to its proper place in the array:
         SWAP SortArray(I), SortArray(High)

         ' Recursively call the QuickSort procedure (pass the
         ' smaller subdivision first to use less stack space):
         If (I - Low) < (High - I) Then
            QuickSort SortArray, Low, I - 1
            QuickSort SortArray, I + 1, High
         Else
            QuickSort SortArray, I + 1, High
            QuickSort SortArray, Low, I - 1
         End If
      End If
   End If
End Sub

Private Sub SWAP(first As String, second As String)
   Dim temp As String
   temp = first
   first = second
   second = temp
End Sub

0
 
LVL 38

Expert Comment

by:PaulHews
ID: 2805757
What element are you sorting on?
0
Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

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.

 
LVL 1

Expert Comment

by:nguyenn
ID: 2805800
Or you can try this option:

    Dim myStr(3) As String
    myStr(0) = "0 Player  gerry
Winnings £  100 Time Taken 0"
    myStr(1) = "4 Player  gerry Winnings £  500 Time Taken 46"
    myStr(2) = "0 Player  gerry Winnings £  100 Time Taken 0"
    myStr(3) = "0 Player  gerry Winnings £  100 Time Taken 15"
   
    For i = 0 To 3
        Asc (myStr(i))
    Next
   
    For i = 3 To 0 Step -1
        List1.AddItem myStr(i)
    Next

In your list you will have:

0 Player  gerry Winnings £  100 Time Taken 0
0 Player  gerry Winnings £  100 Time Taken 0
0 Player  gerry Winnings £  100 Time Taken 15
4 Player  gerry Winnings £  500 Time Taken 46
 




0
 
LVL 1

Expert Comment

by:nguyenn
ID: 2805811
If you want to add these strings to your table, replace List1.AddItem by
your recordset object
0
 
LVL 28

Expert Comment

by:AzraSound
ID: 2805850
if you want to display it visually then a listview would be more appealing, plus it will sort in descending order as opposed to just ascending order like the listbox does...heres an example using your values...if you stored these values in arrays you could easily create a loop to do the same thing:

Private Sub Form_Load()
    ListView1.View = lvwReport
    With ListView1.ColumnHeaders
        .Add , , "Score"
        .Add , , "Player"
        .Add , , "Winnings"
        .Add , , "Time Taken"
    End With
    With ListView1.ListItems
        .Add , , "0"
        .Add , , "4"
        .Add , , "0"
        .Add , , "0"
    End With
    With ListView1
        .ListItems(1).SubItems(1) = "gerry"
        .ListItems(2).SubItems(1) = "gerry"
        .ListItems(3).SubItems(1) = "gerry"
        .ListItems(4).SubItems(1) = "gerry"

        .ListItems(1).SubItems(2) = "100"
        .ListItems(2).SubItems(2) = "100"
        .ListItems(3).SubItems(2) = "100"
        .ListItems(4).SubItems(2) = "100"
       
        .ListItems(1).SubItems(3) = "0"
        .ListItems(2).SubItems(3) = "46"
        .ListItems(3).SubItems(3) = "0"
        .ListItems(4).SubItems(3) = "15"
    End With
    ListView1.Sorted = True
    ListView1.SortKey = 1
    ListView1.SortOrder = lvwDescending
End Sub



0
 

Expert Comment

by:monteh
ID: 2813099
Gentlemen; All of your string sorting routings can be further optimized by merely swaping the BSTR lead bytes. As expected the SWAP requires 3 calls, but only 4 bytes a piece, as opposed to the entire Unicode string. Swapping pointers cost a lot less. Here's the code:

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)


Private Sub Form_Load()

    Dim X As String
    Dim Y As String
    Dim lpX As Long
   
    X = "X"
    Y = "Y"
   
    ' copy into swap temp variable
    CopyMemory ByVal VarPtr(lpX), ByVal VarPtr(X), 4
    ' swap x with y
    CopyMemory ByVal VarPtr(X), ByVal VarPtr(Y), 4
    ' swap y with x
    CopyMemory ByVal VarPtr(Y), ByVal VarPtr(lpX), 4
    ' show me
    Debug.Print "X=" & X ' Prints: X=Y
    Debug.Print "Y=" & Y ' Prints: Y=X
   
End Sub
0
 
LVL 28

Expert Comment

by:AzraSound
ID: 2813174
whats your point?
0
 

Expert Comment

by:monteh
ID: 2813332
I'm sorry if "your string sorting routings can be further optimized by..." doesn't get my point across. I don't think it could have been clearer.

My suggestion was intended for those who write or implement sorting routines, who usually like them to be as fast as they can be.  It was not so intended for the benefit of the original question.

Perhaps I should have tagged it as a comment... oh well, next time.
0
 
LVL 9

Expert Comment

by:GivenRandy
ID: 2813824
I agree with AzraSound -- what's your point?  You didn't provide a complete solution, only a portion which is already in mine (and yours won't work completely anyhow!).

If you REALLY are concerned about speed ("as fast as they can be"), you would you something like the QuickSort approach I mentioned.  The simple swap is very slow for large sets of data.  However, I think the questioner should try my first suggestion and see if the speed is acceptable -- it probably is.
0
 
LVL 9

Expert Comment

by:GivenRandy
ID: 2813829
AzraSounds suggestion of a ListBox is also good and one we use on occasion.  If you don't want to see the ListBox, set Visible to False.  We often use a ListBox instead of a Collection because it is faster (typically 2 to 3 time faster, sometimes more).  However, your string length in the ListBox is limited to 1024 bytes -- don't know why and it makes me question VB's implementation of the ListBox.
0
 
LVL 28

Expert Comment

by:AzraSound
ID: 2814016
actually my suggestion was for a listview to separate the items into columns for a cleaner presentation of the information...



<<Perhaps I should have tagged it as a comment... oh well, next time.>>

you have the option to retract your answer to a comment
0
 

Expert Comment

by:monteh
ID: 2814215
GivenRandy: My suggestion was to improve the speed of the suggested sorting function supplied by you. Nothing more. To be more specific, your sort routine (which looks great) can be further optimized using the following improved SWAP function :)

Private Sub SWAP(first As String, second As String)  

    Dim temp As String
     
    ' copy into swap temp variable
    CopyMemory ByVal VarPtr(temp), ByVal VarPtr(first), 4
    ' swap the string BSTR pointers
    CopyMemory ByVal VarPtr(first), ByVal VarPtr(second), 4
    CopyMemory ByVal VarPtr(second), ByVal VarPtr(temp), 4

End Sub
0
 

Expert Comment

by:monteh
ID: 2814629
monteh changed the proposed answer to a comment
0
 
LVL 9

Expert Comment

by:GivenRandy
ID: 2815455
My mistake.  Thanks for changing to a comment.  You'll get your t-shirt sooner than you think!
0
 

Expert Comment

by:monteh
ID: 2817436
t-shirt?

cheers.
0
 
LVL 2

Author Comment

by:gerrymcd
ID: 2822602
azarsound can u explain the listview usage more!
0
 
LVL 28

Expert Comment

by:AzraSound
ID: 2822723
what do you want to know about it?
0
 
LVL 2

Author Comment

by:gerrymcd
ID: 2838665
i had to do a few modiificatins but tours was the easiest to understand!
0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering 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

I’ve seen a number of people looking for examples of how to access web services from VB6.  I’ve been using a test harness I built in VB6 (using many resources I found online) that I use for small projects to work out how to communicate with web serv…
Have you ever wanted to restrict the users input in a textbox to numbers, and while doing that make sure that they can't 'cheat' by pasting in non-numeric text? Of course you can do that with code you write yourself but it's tedious and error-prone …
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…

831 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