Subversion Repositories DevTools

Rev

Rev 5506 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
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
 
6873 dpurdie 219
		If hiBound >= 1 Then
119 ghuddy 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
 
6873 dpurdie 230
		If hiBound >= 1 Then
119 ghuddy 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
%>