Subversion Repositories DevTools

Rev

Rev 13 | Blame | Compare with Previous | Last modification | View Log | RSS feed

<%
'=============================================================
'//
'//                                             SortHelper
'//
'// version:            1.2
'//     last modified:  11 Jul 2005 15:20 by Sasha Vukovic
'=============================================================
%>
<%
'--------------- Global Constants ----------------

'-------------------------------------------------

Class SortHelper
        Private enumVERSION_SORT
        Private enumSTRING_SORT
        
        Private m_SortType
        
        '-----------------------------------------------------------------------------------------------------------------
        Private Sub SwapRows(ary,row1,row2)
                '== This proc swaps two rows of an array 
                Dim x,tempvar
                
                For x = 0 to Ubound(ary,1)
                        tempvar = ary(x,row1)    
                        ary(x,row1) = ary(x,row2)
                        ary(x,row2) = tempvar
                Next
                
        End Sub
        '------------------------------------------------------------------------------------------------------------------
        Private Sub QuickSort( ByRef vec,loBound,hiBound,SortField)
                
                '==--------------------------------------------------------==
                '== Sort a 2 dimensional array on SortField                ==
                '==                                                        ==
                '== This procedure is adapted from the algorithm given in: ==
                '==    ~ Data Abstractions & Structures using C++ by ~     ==
                '==    ~ Mark Headington and David Riley, pg. 586    ~     ==
                '== Quicksort is the fastest array sorting routine for     ==
                '== unordered arrays.  Its big O is  n log n               ==
                '==                                                        ==
                '== Parameters:                                            ==
                '== vec       - array to be sorted                         ==
                '== SortField - The field to sort on (2nd dimension value) ==
                '== loBound and hiBound are simply the upper and lower     ==
                '==   bounds of the array's 1st dimension.  It's probably  ==
                '==   easiest to use the LBound and UBound functions to    ==
                '==   set these.                                           ==
                '==--------------------------------------------------------==
                
                
                
                Dim pivot(),loSwap,hiSwap,temp,counter
                Redim pivot (Ubound(vec,1))
                
                '== Two items to sort
                if hiBound - loBound = 1 then
                        if IsGreater( vec(SortField,loBound), vec(SortField,hiBound) ) then Call SwapRows(vec,hiBound,loBound)
                End If
                
                '== Three or more items to sort
                For counter = 0 to Ubound(vec,1)
                        pivot(counter) = vec(counter,int((loBound + hiBound) / 2))
                        vec(counter,int((loBound + hiBound) / 2)) = vec(counter,loBound)
                        vec(counter,loBound) = pivot(counter)
                Next
                
                loSwap = loBound + 1
                hiSwap = hiBound
                
                do
                        '== Find the right loSwap
                        
                        while loSwap < hiSwap and ( NOT IsGreater( vec(SortField,loSwap), pivot(SortField) ) )
                                loSwap = loSwap + 1
                        wend
                        
                        '== Find the right hiSwap
                        while IsGreater ( vec(SortField,hiSwap), pivot(SortField) )
                        hiSwap = hiSwap - 1
                        wend
                        
                        
                        '== Swap values if loSwap is less then hiSwap
                        if loSwap < hiSwap then Call SwapRows(vec,loSwap,hiSwap)
                        
                loop while loSwap < hiSwap
                
                For counter = 0 to Ubound(vec,1)
                        vec(counter,loBound) = vec(counter,hiSwap)
                        vec(counter,hiSwap) = pivot(counter)
                Next
                
                '== Recursively call function .. the beauty of Quicksort
                '== 2 or more items in first section
                if loBound < (hiSwap - 1) then Call QuickSort(vec,loBound,hiSwap-1,SortField)
                
                '== 2 or more items in second section
                if hiSwap + 1 < hibound then Call QuickSort(vec,hiSwap+1,hiBound,SortField)
                
        End Sub
        '------------------------------------------------------------------------------------------------------------------
        Private Function IsGreater( ByRef sStringA, ByRef sStringB )
                Select Case m_SortType
                        Case enumVERSION_SORT
                                IsGreater = IsGreaterForVersionSort( sStringA, sStringB )
                                
                        Case enumSTRING_SORT
                                IsGreater = IsGreaterForStringSort( sStringA, sStringB )
                                
                End Select
        End Function
        '------------------------------------------------------------------------------------------------------------------
        Private Function IsGreaterForStringSort( ByRef sStringA, ByRef sStringB )
                IsGreaterForStringSort = Eval( sStringA > sStringB )
        End Function
        '------------------------------------------------------------------------------------------------------------------
        Private Function IsGreaterForVersionSort( ByVal sStringA, ByVal sStringB )
                Dim nMinLen, i, aCharsA, aCharsB, valA, valB
                Dim DoLengthComparison
                Const SEPARATOR = "."
                
                IsGreaterForVersionSort = FALSE
                DoLengthComparison = TRUE
                
                
                ' Replace other delimmiting symbols with dot
                ' This is used to sort version numbers.
                sStringA = Replace( sStringA, "-", SEPARATOR) 
                sStringB = Replace( sStringB, "-", SEPARATOR) 
                sStringA = Replace( sStringA, "_", SEPARATOR) 
                sStringB = Replace( sStringB, "_", SEPARATOR) 
                
                
                ' Split version string with dot separator
                aCharsA = Split(sStringA, SEPARATOR)
                aCharsB = Split(sStringB, SEPARATOR)
                
                
                ' Find which Ubound is smallest
                nMinLen = UBound(aCharsA)
                If nMinLen > UBound(aCharsB) Then nMinLen = UBound(aCharsB)
                
                
                'Response.write "======================================================<br>"
                
                'Response.write sStringA &" is greater then "& sStringB  &"<br>"
                
                ' Content Comparison
                For i = 0 To nMinLen
                        
                        
                        valA = aCharsA(i)
                        valB = aCharsB(i)
                        
                        
                        If IsNumeric(valA)  AND  IsNumeric(valB) Then 
                                'Response.write valA &"IS NUMERIC"& valB &"<br>"
                                
                                ' Do number compare
                                valA = CDbl(valA)
                                valB = CDbl(valB)
                                
                                If valA <> valB Then
                                        
                                        DoLengthComparison = FALSE
                                        
                                        If valA > valB Then
                                                IsGreaterForVersionSort = TRUE
                                                Exit For
                                        Else
                                                Exit For
                                        End If
                                        
                                        
                                End If
                                
                        Else
                                ' Do string compare
                                If valA <> valB Then
                                        
                                        DoLengthComparison = FALSE
                                        
                                        If valA > valB Then
                                                IsGreaterForVersionSort = TRUE
                                                Exit For
                                        Else
                                                Exit For
                                        End If
                                        
                                        
                                End If
                                
                        End If
                        
                Next
                
                ' Continue with Lenght Comparison if required
                If DoLengthComparison AND ( Len(sStringA) > Len(sStringB) ) Then
                        'Response.write "LENGTH COMPARISON<br>"
                        
                        IsGreaterForVersionSort = TRUE
                        
                End If
                
                
                
                'Response.write "RESULT is greater:"& IsGreaterForVersionSort  &"<br>"
                
        End Function    
        '-----------------------------------------------------------------------------------------------------------------
        Public Sub VersionSort( ByRef vec, loBound, hiBound, SortField )
                ' Set default comparison implementation
                m_SortType = enumVERSION_SORT
                
                If hiBound > 1 Then
                        ' Run sorting
                        Call QuickSort( vec, loBound, hiBound, SortField)
                End If
                
        End Sub
        '-----------------------------------------------------------------------------------------------------------------
        Public Sub StringSort( ByRef vec, loBound, hiBound, SortField )
                ' Set default comparison implementation
                m_SortType = enumSTRING_SORT
                
                If hiBound > 1 Then
                        ' Run sorting
                        Call QuickSort( vec, loBound, hiBound, SortField)
                End If
                
        End Sub
        '-----------------------------------------------------------------------------------------------------------------
        Private Sub Class_Initialize()
                ' Set enums
                enumVERSION_SORT = 1
                enumSTRING_SORT = 2
                
        End Sub
        '-----------------------------------------------------------------------------------------------------------------
        Private Sub Class_Terminate()
        End Sub
        '-----------------------------------------------------------------------------------------------------------------
End Class
%>