sorteren op alfabet van een array

Status
Niet open voor verdere reacties.

alberto

Gebruiker
Lid geworden
25 mrt 2005
Berichten
9
Ik wil een array van twee kolommen alfabetisch sorteren. Heeft iemand een algorithme hiervoor?

Voordat iedereen zegt: "sort" zit toch gewoon in VB bij "query": ik heb de Learning Edition van VB6, en daar zit het helaas niet in.
 
voeg me toe op msn; mike@vnx.nl. hoop dat ik je zo beter kan helpen dan hier de heletijd te "slow-posten".

of misschien heeft iemand anders een kort en bondig antwoord ;)
 
Het gaat me er niet zozeer om dat het array 2-dimensionaal is. Ik kan ook de 2 kolommen samenvoegen tot 1 kolom, dat is geen probleem.

Een oplossing met twee loopjes is een eenvoudige oplossing, die heb ik zelf wel eens opgesteld. Echter neemt de rekentijd kwadratisch toe met het aantal elementen. Voor 2000 termen is het bijv. een minuut, maar voor 20000 termen 100 minuten ofwel ruim anderhalf uur!

Ik weet dat wiskundigen een uitgekiende algorithme hiervoor hebben, die werkelijk razendsnel sorteert. Hoogstwaarschijnlijk zit deze ook in de ingebouwde functie van VB. Maar hoe luidt die?!
 
Hai, :D

Als je inderdaad dergelijke hoeveelheden moet sorteren dan zou een ingebouwde functie in VB wel een snellere oplossing zijn..

Helaas werk ik niet veel meer in VB dus kan ik je niet verder helpen aan zo'n functie...

Veel succes! :thumb:
 
In VB zit geen standaard functie om arrays te sorteren.
Je zou gebruik kunnen maken van een ADODB.recordset omdat je deze wel kunt sorteren op een willekeurig veld maar dan moet je eerst de recordset vullen.

Er zijn verschillende manieren om een array te sorteren. Over het algemeen is de quicksort het snelst.

Hieronder de code voor een quicksort van een array.
Als je wilt sorteren op twee velden moet je die eerst aan elkaar plakken en vervolgens sorteren.
De private declare CopyMemory functie kan je weglaten. Deze zit hierin om een en ander te versnellen.

Weest gegroet,
Guus

Code:
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (lpDest As Any, lpSource As Any, ByVal cbCopy As Long)

Public Sub QuickSort(ByRef strArray() As String, _
            Optional ByVal lngMin As Long = -2, _
            Optional ByVal lngMax As Long = -2)
' This subroutine takes an array as an argument, and will sort the
' array in ascending ASCII value.
' Case insensitive sort

    Dim lngI       As Long
    Dim lngJ       As Long
    Dim lngMid     As Long
    Dim strTestVal As String

    If lngMin = -2 Then
        lngMin = LBound(strArray, 1)
    End If
    If lngMax = -2 Then
        lngMax = UBound(strArray, 1)
    End If

    If lngMin < lngMax Then
        lngMid = (lngMin + lngMax) \ 2
        strTestVal = UCase$(strArray(lngMid))
        lngI = lngMin
        lngJ = lngMax
        Do
            Do While UCase$(strArray(lngI)) < strTestVal
                lngI = lngI + 1
            Loop
            Do While UCase$(strArray(lngJ)) > strTestVal
                lngJ = lngJ - 1
            Loop
            If lngI <= lngJ Then
                SwapStrings strArray(lngI), strArray(lngJ)
                lngI = lngI + 1
                lngJ = lngJ - 1
            End If
            
        Loop Until lngI > lngJ

        ' Optimize sort by sorting smaller segment first
        If lngJ <= lngMid Then
            Call QuickSort(strArray, lngMin, lngJ)
            Call QuickSort(strArray, lngI, lngMax)
        Else
            Call QuickSort(strArray, lngI, lngMax)
            Call QuickSort(strArray, lngMin, lngJ)
        End If
    End If
End Sub

Private Sub SwapStrings(Item1 As String, Item2 As String)

    Dim TmpVal As Long
    
    CopyMemory TmpVal, ByVal VarPtr(Item1), 4
    CopyMemory ByVal VarPtr(Item1), ByVal VarPtr(Item2), 4
    CopyMemory ByVal VarPtr(Item2), TmpVal, 4
    
End Sub
 
Laatst bewerkt:
Hallo Guus2005,

Ik denk dat deze routine wel ongeveer is wat ik zoek.
Maar ik moet hem nog testen, heb dus nog geen oordeel erover.
Voorlopig veel dank!
alberto
 
Hallo Guus 2005,
Hier een eerste reactie.
De functie CopyMemory zit niet in de subset van VB.
Maar ik neem aan dat die subroutine SwapStrings alleen maar twee strings verwisselt?
Dus kan ik ook geven:?

Private Sub SwapStrings(Item 1 As String, Item2 As String)

Dim strHulp As String
strHulp = Item1
Item1 = Item2
Item2 = strHulp

End Sub

Groetjes,
alberto
 
Ja dat werkt ook.

Code:
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (lpDest As Any, lpSource As Any, ByVal cbCopy As Long)

maakt gebruik van een API en werkt sneller. Praktisch als je verzameling elementen erg groot is.

probeer maar eens in een lus en voer die 10.000 keer uit.
de api werkt stukken sneller.

Weest gegroet,
Guus
 
Hallo Guus,
Van je verhaal over API begrijp ik niets.
Maar ik heb mijn oplossinkje toegepast, in plaats van die subroutine met CopyMemory erin, en het geheel werkt nu goed.
Een array sorteren met 20000 items duurde op mijn computer 3 seconden! Verbluffend.
Probleem dus opgelost.
alberto
 
Gebruik de code die ik stuurde met de copymemory API call en de verwerkingstijd wordt teruggebracht naar 1 seconde!!

Als je meer tips wil hebben over het sneller maken van code hoor ik het wel.

Weest gegroet,

Guus
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan