| 119 |
ghuddy |
1 |
<%
|
|
|
2 |
'=============================================================
|
|
|
3 |
'//
|
|
|
4 |
'// SortHelper
|
|
|
5 |
'//
|
|
|
6 |
'// version: 1.2
|
|
|
7 |
'// last modified: 11 Jul 2005 15:20 by Sasha Vukovic
|
|
|
8 |
'=============================================================
|
|
|
9 |
%>
|
|
|
10 |
<%
|
|
|
11 |
'--------------- Global Constants ----------------
|
|
|
12 |
|
|
|
13 |
'-------------------------------------------------
|
|
|
14 |
|
|
|
15 |
Class SortHelper
|
|
|
16 |
Private enumVERSION_SORT
|
|
|
17 |
Private enumSTRING_SORT
|
|
|
18 |
|
|
|
19 |
Private m_SortType
|
|
|
20 |
|
|
|
21 |
'-----------------------------------------------------------------------------------------------------------------
|
|
|
22 |
Private Sub SwapRows(ary,row1,row2)
|
|
|
23 |
'== This proc swaps two rows of an array
|
|
|
24 |
Dim x,tempvar
|
|
|
25 |
|
|
|
26 |
For x = 0 to Ubound(ary,1)
|
|
|
27 |
tempvar = ary(x,row1)
|
|
|
28 |
ary(x,row1) = ary(x,row2)
|
|
|
29 |
ary(x,row2) = tempvar
|
|
|
30 |
Next
|
|
|
31 |
|
|
|
32 |
End Sub
|
|
|
33 |
'------------------------------------------------------------------------------------------------------------------
|
|
|
34 |
Private Sub QuickSort( ByRef vec,loBound,hiBound,SortField)
|
|
|
35 |
|
|
|
36 |
'==--------------------------------------------------------==
|
|
|
37 |
'== Sort a 2 dimensional array on SortField ==
|
|
|
38 |
'== ==
|
|
|
39 |
'== This procedure is adapted from the algorithm given in: ==
|
|
|
40 |
'== ~ Data Abstractions & Structures using C++ by ~ ==
|
|
|
41 |
'== ~ Mark Headington and David Riley, pg. 586 ~ ==
|
|
|
42 |
'== Quicksort is the fastest array sorting routine for ==
|
|
|
43 |
'== unordered arrays. Its big O is n log n ==
|
|
|
44 |
'== ==
|
|
|
45 |
'== Parameters: ==
|
|
|
46 |
'== vec - array to be sorted ==
|
|
|
47 |
'== SortField - The field to sort on (2nd dimension value) ==
|
|
|
48 |
'== loBound and hiBound are simply the upper and lower ==
|
|
|
49 |
'== bounds of the array's 1st dimension. It's probably ==
|
|
|
50 |
'== easiest to use the LBound and UBound functions to ==
|
|
|
51 |
'== set these. ==
|
|
|
52 |
'==--------------------------------------------------------==
|
|
|
53 |
|
|
|
54 |
|
|
|
55 |
|
|
|
56 |
Dim pivot(),loSwap,hiSwap,temp,counter
|
|
|
57 |
Redim pivot (Ubound(vec,1))
|
|
|
58 |
|
|
|
59 |
'== Two items to sort
|
|
|
60 |
if hiBound - loBound = 1 then
|
|
|
61 |
if IsGreater( vec(SortField,loBound), vec(SortField,hiBound) ) then Call SwapRows(vec,hiBound,loBound)
|
|
|
62 |
End If
|
|
|
63 |
|
|
|
64 |
'== Three or more items to sort
|
|
|
65 |
For counter = 0 to Ubound(vec,1)
|
|
|
66 |
pivot(counter) = vec(counter,int((loBound + hiBound) / 2))
|
|
|
67 |
vec(counter,int((loBound + hiBound) / 2)) = vec(counter,loBound)
|
|
|
68 |
vec(counter,loBound) = pivot(counter)
|
|
|
69 |
Next
|
|
|
70 |
|
|
|
71 |
loSwap = loBound + 1
|
|
|
72 |
hiSwap = hiBound
|
|
|
73 |
|
|
|
74 |
do
|
|
|
75 |
'== Find the right loSwap
|
|
|
76 |
|
|
|
77 |
while loSwap < hiSwap and ( NOT IsGreater( vec(SortField,loSwap), pivot(SortField) ) )
|
|
|
78 |
loSwap = loSwap + 1
|
|
|
79 |
wend
|
|
|
80 |
|
|
|
81 |
'== Find the right hiSwap
|
|
|
82 |
while IsGreater ( vec(SortField,hiSwap), pivot(SortField) )
|
|
|
83 |
hiSwap = hiSwap - 1
|
|
|
84 |
wend
|
|
|
85 |
|
|
|
86 |
|
|
|
87 |
'== Swap values if loSwap is less then hiSwap
|
|
|
88 |
if loSwap < hiSwap then Call SwapRows(vec,loSwap,hiSwap)
|
|
|
89 |
|
|
|
90 |
loop while loSwap < hiSwap
|
|
|
91 |
|
|
|
92 |
For counter = 0 to Ubound(vec,1)
|
|
|
93 |
vec(counter,loBound) = vec(counter,hiSwap)
|
|
|
94 |
vec(counter,hiSwap) = pivot(counter)
|
|
|
95 |
Next
|
|
|
96 |
|
|
|
97 |
'== Recursively call function .. the beauty of Quicksort
|
|
|
98 |
'== 2 or more items in first section
|
|
|
99 |
if loBound < (hiSwap - 1) then Call QuickSort(vec,loBound,hiSwap-1,SortField)
|
|
|
100 |
|
|
|
101 |
'== 2 or more items in second section
|
|
|
102 |
if hiSwap + 1 < hibound then Call QuickSort(vec,hiSwap+1,hiBound,SortField)
|
|
|
103 |
|
|
|
104 |
End Sub
|
|
|
105 |
'------------------------------------------------------------------------------------------------------------------
|
|
|
106 |
Private Function IsGreater( ByRef sStringA, ByRef sStringB )
|
|
|
107 |
Select Case m_SortType
|
|
|
108 |
Case enumVERSION_SORT
|
|
|
109 |
IsGreater = IsGreaterForVersionSort( sStringA, sStringB )
|
|
|
110 |
|
|
|
111 |
Case enumSTRING_SORT
|
|
|
112 |
IsGreater = IsGreaterForStringSort( sStringA, sStringB )
|
|
|
113 |
|
|
|
114 |
End Select
|
|
|
115 |
End Function
|
|
|
116 |
'------------------------------------------------------------------------------------------------------------------
|
|
|
117 |
Private Function IsGreaterForStringSort( ByRef sStringA, ByRef sStringB )
|
|
|
118 |
IsGreaterForStringSort = Eval( sStringA > sStringB )
|
|
|
119 |
End Function
|
|
|
120 |
'------------------------------------------------------------------------------------------------------------------
|
|
|
121 |
Private Function IsGreaterForVersionSort( ByVal sStringA, ByVal sStringB )
|
|
|
122 |
Dim nMinLen, i, aCharsA, aCharsB, valA, valB
|
|
|
123 |
Dim DoLengthComparison
|
|
|
124 |
Const SEPARATOR = "."
|
|
|
125 |
|
|
|
126 |
IsGreaterForVersionSort = FALSE
|
|
|
127 |
DoLengthComparison = TRUE
|
|
|
128 |
|
|
|
129 |
|
|
|
130 |
' Replace other delimmiting symbols with dot
|
|
|
131 |
' This is used to sort version numbers.
|
|
|
132 |
sStringA = Replace( sStringA, "-", SEPARATOR)
|
|
|
133 |
sStringB = Replace( sStringB, "-", SEPARATOR)
|
|
|
134 |
sStringA = Replace( sStringA, "_", SEPARATOR)
|
|
|
135 |
sStringB = Replace( sStringB, "_", SEPARATOR)
|
|
|
136 |
|
|
|
137 |
|
|
|
138 |
' Split version string with dot separator
|
|
|
139 |
aCharsA = Split(sStringA, SEPARATOR)
|
|
|
140 |
aCharsB = Split(sStringB, SEPARATOR)
|
|
|
141 |
|
|
|
142 |
|
|
|
143 |
' Find which Ubound is smallest
|
|
|
144 |
nMinLen = UBound(aCharsA)
|
|
|
145 |
If nMinLen > UBound(aCharsB) Then nMinLen = UBound(aCharsB)
|
|
|
146 |
|
|
|
147 |
|
|
|
148 |
'Response.write "======================================================<br>"
|
|
|
149 |
|
|
|
150 |
'Response.write sStringA &" is greater then "& sStringB &"<br>"
|
|
|
151 |
|
|
|
152 |
' Content Comparison
|
|
|
153 |
For i = 0 To nMinLen
|
|
|
154 |
|
|
|
155 |
|
|
|
156 |
valA = aCharsA(i)
|
|
|
157 |
valB = aCharsB(i)
|
|
|
158 |
|
|
|
159 |
|
|
|
160 |
If IsNumeric(valA) AND IsNumeric(valB) Then
|
|
|
161 |
'Response.write valA &"IS NUMERIC"& valB &"<br>"
|
|
|
162 |
|
|
|
163 |
' Do number compare
|
|
|
164 |
valA = CDbl(valA)
|
|
|
165 |
valB = CDbl(valB)
|
|
|
166 |
|
|
|
167 |
If valA <> valB Then
|
|
|
168 |
|
|
|
169 |
DoLengthComparison = FALSE
|
|
|
170 |
|
|
|
171 |
If valA > valB Then
|
|
|
172 |
IsGreaterForVersionSort = TRUE
|
|
|
173 |
Exit For
|
|
|
174 |
Else
|
|
|
175 |
Exit For
|
|
|
176 |
End If
|
|
|
177 |
|
|
|
178 |
|
|
|
179 |
End If
|
|
|
180 |
|
|
|
181 |
Else
|
|
|
182 |
' Do string compare
|
|
|
183 |
If valA <> valB Then
|
|
|
184 |
|
|
|
185 |
DoLengthComparison = FALSE
|
|
|
186 |
|
|
|
187 |
If valA > valB Then
|
|
|
188 |
IsGreaterForVersionSort = TRUE
|
|
|
189 |
Exit For
|
|
|
190 |
Else
|
|
|
191 |
Exit For
|
|
|
192 |
End If
|
|
|
193 |
|
|
|
194 |
|
|
|
195 |
End If
|
|
|
196 |
|
|
|
197 |
End If
|
|
|
198 |
|
|
|
199 |
Next
|
|
|
200 |
|
|
|
201 |
' Continue with Lenght Comparison if required
|
|
|
202 |
If DoLengthComparison AND ( Len(sStringA) > Len(sStringB) ) Then
|
|
|
203 |
'Response.write "LENGTH COMPARISON<br>"
|
|
|
204 |
|
|
|
205 |
IsGreaterForVersionSort = TRUE
|
|
|
206 |
|
|
|
207 |
End If
|
|
|
208 |
|
|
|
209 |
|
|
|
210 |
|
|
|
211 |
'Response.write "RESULT is greater:"& IsGreaterForVersionSort &"<br>"
|
|
|
212 |
|
|
|
213 |
End Function
|
|
|
214 |
'-----------------------------------------------------------------------------------------------------------------
|
|
|
215 |
Public Sub VersionSort( ByRef vec, loBound, hiBound, SortField )
|
|
|
216 |
' Set default comparison implementation
|
|
|
217 |
m_SortType = enumVERSION_SORT
|
|
|
218 |
|
|
|
219 |
If hiBound > 1 Then
|
|
|
220 |
' Run sorting
|
|
|
221 |
Call QuickSort( vec, loBound, hiBound, SortField)
|
|
|
222 |
End If
|
|
|
223 |
|
|
|
224 |
End Sub
|
|
|
225 |
'-----------------------------------------------------------------------------------------------------------------
|
|
|
226 |
Public Sub StringSort( ByRef vec, loBound, hiBound, SortField )
|
|
|
227 |
' Set default comparison implementation
|
|
|
228 |
m_SortType = enumSTRING_SORT
|
|
|
229 |
|
|
|
230 |
If hiBound > 1 Then
|
|
|
231 |
' Run sorting
|
|
|
232 |
Call QuickSort( vec, loBound, hiBound, SortField)
|
|
|
233 |
End If
|
|
|
234 |
|
|
|
235 |
End Sub
|
|
|
236 |
'-----------------------------------------------------------------------------------------------------------------
|
|
|
237 |
Private Sub Class_Initialize()
|
|
|
238 |
' Set enums
|
|
|
239 |
enumVERSION_SORT = 1
|
|
|
240 |
enumSTRING_SORT = 2
|
|
|
241 |
|
|
|
242 |
End Sub
|
|
|
243 |
'-----------------------------------------------------------------------------------------------------------------
|
|
|
244 |
Private Sub Class_Terminate()
|
|
|
245 |
End Sub
|
|
|
246 |
'-----------------------------------------------------------------------------------------------------------------
|
|
|
247 |
End Class
|
|
|
248 |
%>
|