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 SortHelperPrivate enumVERSION_SORTPrivate enumSTRING_SORTPrivate m_SortType'-----------------------------------------------------------------------------------------------------------------Private Sub SwapRows(ary,row1,row2)'== This proc swaps two rows of an arrayDim x,tempvarFor x = 0 to Ubound(ary,1)tempvar = ary(x,row1)ary(x,row1) = ary(x,row2)ary(x,row2) = tempvarNextEnd 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,counterRedim pivot (Ubound(vec,1))'== Two items to sortif hiBound - loBound = 1 thenif IsGreater( vec(SortField,loBound), vec(SortField,hiBound) ) then Call SwapRows(vec,hiBound,loBound)End If'== Three or more items to sortFor 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)NextloSwap = loBound + 1hiSwap = hiBounddo'== Find the right loSwapwhile loSwap < hiSwap and ( NOT IsGreater( vec(SortField,loSwap), pivot(SortField) ) )loSwap = loSwap + 1wend'== Find the right hiSwapwhile IsGreater ( vec(SortField,hiSwap), pivot(SortField) )hiSwap = hiSwap - 1wend'== Swap values if loSwap is less then hiSwapif loSwap < hiSwap then Call SwapRows(vec,loSwap,hiSwap)loop while loSwap < hiSwapFor 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 sectionif loBound < (hiSwap - 1) then Call QuickSort(vec,loBound,hiSwap-1,SortField)'== 2 or more items in second sectionif hiSwap + 1 < hibound then Call QuickSort(vec,hiSwap+1,hiBound,SortField)End Sub'------------------------------------------------------------------------------------------------------------------Private Function IsGreater( ByRef sStringA, ByRef sStringB )Select Case m_SortTypeCase enumVERSION_SORTIsGreater = IsGreaterForVersionSort( sStringA, sStringB )Case enumSTRING_SORTIsGreater = IsGreaterForStringSort( sStringA, sStringB )End SelectEnd 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, valBDim DoLengthComparisonConst SEPARATOR = "."IsGreaterForVersionSort = FALSEDoLengthComparison = 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 separatoraCharsA = Split(sStringA, SEPARATOR)aCharsB = Split(sStringB, SEPARATOR)' Find which Ubound is smallestnMinLen = UBound(aCharsA)If nMinLen > UBound(aCharsB) Then nMinLen = UBound(aCharsB)'Response.write "======================================================<br>"'Response.write sStringA &" is greater then "& sStringB &"<br>"' Content ComparisonFor i = 0 To nMinLenvalA = aCharsA(i)valB = aCharsB(i)If IsNumeric(valA) AND IsNumeric(valB) Then'Response.write valA &"IS NUMERIC"& valB &"<br>"' Do number comparevalA = CDbl(valA)valB = CDbl(valB)If valA <> valB ThenDoLengthComparison = FALSEIf valA > valB ThenIsGreaterForVersionSort = TRUEExit ForElseExit ForEnd IfEnd IfElse' Do string compareIf valA <> valB ThenDoLengthComparison = FALSEIf valA > valB ThenIsGreaterForVersionSort = TRUEExit ForElseExit ForEnd IfEnd IfEnd IfNext' Continue with Lenght Comparison if requiredIf DoLengthComparison AND ( Len(sStringA) > Len(sStringB) ) Then'Response.write "LENGTH COMPARISON<br>"IsGreaterForVersionSort = TRUEEnd If'Response.write "RESULT is greater:"& IsGreaterForVersionSort &"<br>"End Function'-----------------------------------------------------------------------------------------------------------------Public Sub VersionSort( ByRef vec, loBound, hiBound, SortField )' Set default comparison implementationm_SortType = enumVERSION_SORTIf hiBound > 1 Then' Run sortingCall QuickSort( vec, loBound, hiBound, SortField)End IfEnd Sub'-----------------------------------------------------------------------------------------------------------------Public Sub StringSort( ByRef vec, loBound, hiBound, SortField )' Set default comparison implementationm_SortType = enumSTRING_SORTIf hiBound > 1 Then' Run sortingCall QuickSort( vec, loBound, hiBound, SortField)End IfEnd Sub'-----------------------------------------------------------------------------------------------------------------Private Sub Class_Initialize()' Set enumsenumVERSION_SORT = 1enumSTRING_SORT = 2End Sub'-----------------------------------------------------------------------------------------------------------------Private Sub Class_Terminate()End Sub'-----------------------------------------------------------------------------------------------------------------End Class%>