Can speed it up a bit and simplify it a bit by avoiding the second
conversion array and
handle the conversion back to the original characters in the counting sort:
Option Explicit
Private lStartTime As Long
Private Declare Function timeGetTime Lib "winmm.dll" () As Long
Private arrLookup(0 To 255) As Byte
Private bFilledLookupArray1 As Boolean
Sub test()
Dim i As Long
Dim str As String
Dim strSorted As String
Dim bSortAaBb As Boolean
Dim bCountingSort As Boolean
Dim bUseSortCharacters As Boolean
str = "ZYXWVUTSRQPONMLKJIHGFEDCBA zyxwvutsrqponmlkjihgfedcba 9876543210
?/><||||||¬¬¬¬,."
If MsgBox("Use the CountingSort?", vbYesNo, "sorting string") = vbYes Then
bCountingSort = True
If MsgBox("Sort as AaBbCc etc.?", vbYesNo, "sorting string") = vbYes
Then
bSortAaBb = True
End If
Else
If MsgBox("Use SortCharacters?", vbYesNo, "sorting string") = vbYes Then
bUseSortCharacters = True
End If
End If
StartSW
If bCountingSort Then
For i = 0 To 1000
strSorted = SortString(str, bSortAaBb)
Next i
Else
If bUseSortCharacters Then
For i = 0 To 1000
strSorted = SortCharacters(str)
Next i
Else
For i = 0 To 1000
strSorted = SortString2(str)
Next i
End If
End If
StopSW
MsgBox strSorted, , "sorted string"
End Sub
Function SortString(strString As String, Optional bSortAaBb As Boolean) As
String
Dim i As Long
Dim btArray() As Byte
Dim btArray2() As Byte
btArray = strString
btArray2 = CountingSortByte1D(btArray, bSortAaBb)
SortString = ByteArrayToString(btArray2)
End Function
Function CountingSortByte1D(arrByte() As Byte, bSortAaBb As Boolean) As
Byte()
Dim i As Long
Dim LB As Long
Dim UB As Long
Dim arrCount() As Long
Dim arrByte2() As Byte
Dim arrByteSorted() As Byte
Dim lThisCount As Long
Dim lNext_Offset As Long
LB = LBound(arrByte)
UB = UBound(arrByte)
If bSortAaBb Then
If bFilledLookupArray1 = False Then
FillLookupArray1
End If
ReDim arrByte2(0 To UB) As Byte
For i = 0 To UB Step 2
arrByte2(i) = arrLookup(arrByte(i))
Next i
End If
'Create the Counts array
ReDim arrCount(0 To 255)
'create the sorted return array
ReDim arrByteSorted(LB To UB \ 2) As Byte
'Count the items
If bSortAaBb Then
For i = LB To UB Step 2
arrCount(arrByte2(i)) = arrCount(arrByte2(i)) + 1
Next i
Else
For i = LB To UB Step 2
arrCount(arrByte(i)) = arrCount(arrByte(i)) + 1
Next i
End If
'Convert the arrCount into offsets
lNext_Offset = LB
For i = 0 To 255
lThisCount = arrCount(i)
arrCount(i) = lNext_Offset
lNext_Offset = lNext_Offset + lThisCount
Next i
'Place the items in the sorted array
If bSortAaBb Then
For i = LB To UB Step 2
arrByteSorted(arrCount(arrByte2(i))) = arrByte(i)
arrCount(arrByte2(i)) = arrCount(arrByte2(i)) + 1
Next i
Else
For i = LB To UB Step 2
arrByteSorted(arrCount(arrByte(i))) = arrByte(i)
arrCount(arrByte(i)) = arrCount(arrByte(i)) + 1
Next i
End If
CountingSortByte1D = arrByteSorted
End Function
Function SortString2(ByVal strIn) As String
Dim i As Long
Dim j As Long
Dim s1 As String
Dim s2 As String
For i = 1 To (Len(strIn) - 1)
For j = (i + 1) To Len(strIn)
s1 = Mid$(strIn, i, 1)
s2 = Mid$(strIn, j, 1)
If StrComp(s1, s2, vbTextCompare) = 1 Then
Mid$(strIn, i, 1) = s2
Mid$(strIn, j, 1) = s1
End If
Next j
Next i
SortString2 = strIn
End Function
Function SortCharacters(ByVal S As String) As String
Dim X As Long
Dim Z As Long
Dim Cnt As Long
ReDim C(1 To Len(S)) As Long
For X = 1 To Len(S)
For Z = 1 To Len(S)
If Mid(S, Z, 1) <= Mid(S, X, 1) Then C(X) = C(X) + 1
Next
Next
SortCharacters = String(Len(S), Chr$(1))
For X = 1 To Len(S)
Mid(SortCharacters, C(X), 1) = Mid(S, X, 1)
Next
For X = Len(S) - 1 To 1 Step -1
If Mid(SortCharacters, X, 1) = Chr$(1) Then
Mid(SortCharacters, X, 1) = Mid(SortCharacters, X + 1, 1)
End If
Next
End Function
Sub FillLookupArray1()
arrLookup(0) = 255
arrLookup(1) = 11
arrLookup(2) = 12
arrLookup(3) = 13
arrLookup(4) = 14
arrLookup(5) = 15
arrLookup(6) = 16
arrLookup(7) = 17
arrLookup(8) = 18
arrLookup(9) = 49
arrLookup(10) = 50
arrLookup(11) = 51
arrLookup(12) = 52
arrLookup(13) = 53
arrLookup(14) = 19
arrLookup(15) = 20
arrLookup(16) = 21
arrLookup(17) = 22
arrLookup(18) = 23
arrLookup(19) = 24
arrLookup(20) = 25
arrLookup(21) = 26
arrLookup(22) = 27
arrLookup(23) = 28
arrLookup(24) = 29
arrLookup(25) = 30
arrLookup(26) = 31
arrLookup(27) = 32
arrLookup(28) = 33
arrLookup(29) = 34
arrLookup(30) = 35
arrLookup(31) = 36
arrLookup(32) = 47
arrLookup(33) = 54
arrLookup(34) = 55
arrLookup(35) = 56
arrLookup(36) = 57
arrLookup(37) = 58
arrLookup(38) = 59
arrLookup(39) = 10
arrLookup(40) = 60
arrLookup(41) = 61
arrLookup(42) = 62
arrLookup(43) = 97
arrLookup(44) = 63
arrLookup(45) = 43
arrLookup(46) = 64
arrLookup(47) = 65
arrLookup(48) = 0
arrLookup(49) = 1
arrLookup(50) = 2
arrLookup(51) = 3
arrLookup(52) = 4
arrLookup(53) = 5
arrLookup(54) = 6
arrLookup(55) = 7
arrLookup(56) = 8
arrLookup(57) = 9
arrLookup(58) = 66
arrLookup(59) = 67
arrLookup(60) = 98
arrLookup(61) = 99
arrLookup(62) = 100
arrLookup(63) = 68
arrLookup(64) = 69
arrLookup(65) = 130
arrLookup(66) = 147
arrLookup(67) = 149
arrLookup(68) = 153
arrLookup(69) = 157
arrLookup(70) = 167
arrLookup(71) = 170
arrLookup(72) = 172
arrLookup(73) = 174
arrLookup(74) = 184
arrLookup(75) = 186
arrLookup(76) = 188
arrLookup(77) = 190
arrLookup(78) = 192
arrLookup(79) = 196
arrLookup(80) = 213
arrLookup(81) = 215
arrLookup(82) = 217
arrLookup(83) = 219
arrLookup(84) = 224
arrLookup(85) = 229
arrLookup(86) = 239
arrLookup(87) = 241
arrLookup(88) = 243
arrLookup(89) = 245
arrLookup(90) = 251
arrLookup(91) = 70
arrLookup(92) = 71
arrLookup(93) = 72
arrLookup(94) = 73
arrLookup(95) = 75
arrLookup(96) = 76
arrLookup(97) = 131
arrLookup(98) = 148
arrLookup(99) = 150
arrLookup(100) = 154
arrLookup(101) = 158
arrLookup(102) = 168
arrLookup(103) = 171
arrLookup(104) = 173
arrLookup(105) = 175
arrLookup(106) = 185
arrLookup(107) = 187
arrLookup(108) = 189
arrLookup(109) = 191
arrLookup(110) = 193
arrLookup(111) = 197
arrLookup(112) = 214
arrLookup(113) = 216
arrLookup(114) = 218
arrLookup(115) = 220
arrLookup(116) = 225
arrLookup(117) = 230
arrLookup(118) = 240
arrLookup(119) = 242
arrLookup(120) = 244
arrLookup(121) = 246
arrLookup(122) = 252
arrLookup(123) = 77
arrLookup(124) = 78
arrLookup(125) = 79
arrLookup(126) = 80
arrLookup(127) = 37
arrLookup(128) = 123
arrLookup(129) = 38
arrLookup(130) = 91
arrLookup(131) = 169
arrLookup(132) = 94
arrLookup(133) = 121
arrLookup(134) = 118
arrLookup(135) = 119
arrLookup(136) = 74
arrLookup(137) = 122
arrLookup(138) = 221
arrLookup(139) = 95
arrLookup(140) = 211
arrLookup(141) = 39
arrLookup(142) = 253
arrLookup(143) = 40
arrLookup(144) = 41
arrLookup(145) = 89
arrLookup(146) = 90
arrLookup(147) = 92
arrLookup(148) = 93
arrLookup(149) = 120
arrLookup(150) = 45
arrLookup(151) = 46
arrLookup(152) = 88
arrLookup(153) = 228
arrLookup(154) = 222
arrLookup(155) = 96
arrLookup(156) = 212
arrLookup(157) = 42
arrLookup(158) = 254
arrLookup(159) = 249
arrLookup(160) = 48
arrLookup(161) = 81
arrLookup(162) = 106
arrLookup(163) = 107
arrLookup(164) = 108
arrLookup(165) = 109
arrLookup(166) = 82
arrLookup(167) = 110
arrLookup(168) = 83
arrLookup(169) = 111
arrLookup(170) = 132
arrLookup(171) = 102
arrLookup(172) = 112
arrLookup(173) = 44
arrLookup(174) = 113
arrLookup(175) = 84
arrLookup(176) = 114
arrLookup(177) = 101
arrLookup(178) = 128
arrLookup(179) = 129
arrLookup(180) = 85
arrLookup(181) = 115
arrLookup(182) = 116
arrLookup(183) = 117
arrLookup(184) = 86
arrLookup(185) = 127
arrLookup(186) = 198
arrLookup(187) = 103
arrLookup(188) = 124
arrLookup(189) = 125
arrLookup(190) = 126
arrLookup(191) = 87
arrLookup(192) = 135
arrLookup(193) = 133
arrLookup(194) = 137
arrLookup(195) = 141
arrLookup(196) = 139
arrLookup(197) = 143
arrLookup(198) = 145
arrLookup(199) = 151
arrLookup(200) = 161
arrLookup(201) = 159
arrLookup(202) = 163
arrLookup(203) = 165
arrLookup(204) = 178
arrLookup(205) = 176
arrLookup(206) = 180
arrLookup(207) = 182
arrLookup(208) = 155
arrLookup(209) = 194
arrLookup(210) = 201
arrLookup(211) = 199
arrLookup(212) = 203
arrLookup(213) = 207
arrLookup(214) = 205
arrLookup(215) = 104
arrLookup(216) = 209
arrLookup(217) = 233
arrLookup(218) = 231
arrLookup(219) = 235
arrLookup(220) = 237
arrLookup(221) = 247
arrLookup(222) = 226
arrLookup(223) = 223
arrLookup(224) = 136
arrLookup(225) = 134
arrLookup(226) = 138
arrLookup(227) = 142
arrLookup(228) = 140
arrLookup(229) = 144
arrLookup(230) = 146
arrLookup(231) = 152
arrLookup(232) = 162
arrLookup(233) = 160
arrLookup(234) = 164
arrLookup(235) = 166
arrLookup(236) = 179
arrLookup(237) = 177
arrLookup(238) = 181
arrLookup(239) = 183
arrLookup(240) = 156
arrLookup(241) = 195
arrLookup(242) = 202
arrLookup(243) = 200
arrLookup(244) = 204
arrLookup(245) = 208
arrLookup(246) = 206
arrLookup(247) = 105
arrLookup(248) = 210
arrLookup(249) = 234
arrLookup(250) = 232
arrLookup(251) = 236
arrLookup(252) = 238
arrLookup(253) = 248
arrLookup(254) = 227
arrLookup(255) = 250
bFilledLookupArray1 = True
End Sub
Function ByteArrayToString(btArray() As Byte) As String
Dim sAns As String
Dim lPos As Long
sAns = StrConv(btArray, vbUnicode)
lPos = InStr(sAns, Chr(0))
If lPos > 0 Then
sAns = Left(sAns, lPos - 1)
End If
ByteArrayToString = sAns
End Function
Sub StartSW()
lStartTime = timeGetTime()
End Sub
Function StopSW(Optional bMsgBox As Boolean = True, _
Optional vMessage As Variant, _
Optional lMinimumTimeToShow As Long = -1) As Variant
Dim lTime As Long
lTime = timeGetTime() - lStartTime
If lTime > lMinimumTimeToShow Then
If IsMissing(vMessage) Then
StopSW = lTime
Else
StopSW = lTime & " - " & vMessage
End If
End If
If bMsgBox Then
If lTime > lMinimumTimeToShow Then
MsgBox "Done in " & lTime & " msecs", , vMessage
End If
End If
End Function
RBS