Jose,
Any CWSTR,CBSTR Array functions (SCAN,SORT) on your ToDo list?
James
I'm afraid not. They're not strings, but pointers to classes. This will make the task slow and very difficult.
Probably not very speedy but ....
'=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
'I believe the QuickSort is from Ethan Winers ported to Fb by yetifoot.
'=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
#include "Afx/AfxStr.inc"
Sub QuickSort(ArrayToSort() As CWSTR, ByVal StartEl As Long, ByVal NumEls As Long)
'************************************************************
'Standard Non-Recursive QuickSort Routine
'************************************************************
Dim As CWStr Temp
Dim As Long First, Last, i, j, StackPtr
Redim As Long QStack(NumEls \ 5 + 10)
First = StartEl
Last = StartEl + NumEls - 1
Do
Do
Temp = ArrayToSort((Last + First) \ 2)
i = First
j = Last
Do
While ArrayToSort(i) < Temp ' Swap < for > to do in descending order
i = i + 1
Wend
While ArrayToSort(j) > Temp ' Swap > for < to do in descending order
j = j - 1
Wend
If i > j Then Exit Do
If i < j Then Swap ArrayToSort(i), ArrayToSort(j)
i = i + 1
j = j - 1
Loop While i <= j
If i < Last Then
QStack(StackPtr) = i
QStack(StackPtr + 1) = Last
StackPtr = StackPtr + 2
End If
Last = j
Loop While First < Last
If StackPtr = 0 Then Exit Do
StackPtr = StackPtr - 2
First = QStack(StackPtr)
Last = QStack(StackPtr + 1)
Loop
Erase QStack
End Sub
'==============================================================================
'Case insensitive Array Scan
'------------------------------------------------------------------------------
Function CWStrArrayScan(sArray() As CWStr,sToMatch As CWStr) As Long
Dim As Long i,j,sToMatchLen
Dim As CWStr S1,S2
S1 = Ucase(sToMatch)
sToMatchLen = Len(sToMatch)
Function = 1
For i = LBound(sArray) To UBound(sArray)
j+=1
If Len(sArray(i)) = sToMatchLen Then
S2 = Ucase(sArray(i))
If S2 = S1 Then
Return j
EndIf
EndIf
Next i
End Function
'==============================================================================
Dim As CWStr str_array(0 To 4)
Dim As Long i
str_array(0) = "Zob"
str_array(1) = "Bob"
str_array(2) = "Hello"
str_array(3) = "Job"
str_array(4) = "Fob"
QuickSort(str_array(), 0, 5)
For i = 0 To 4
Print str_array(i)
Next i
i = CWstrArrayScan(str_array(),"job")
Print "i = ";i
sleep
The C runtime already provides a qsort function.
There are a couple of problems to use qsort with an array of CWSTRs.
'// qsort CWStr comparison function
FUNCTION AfxCWstrCompare CDECL (BYVAL a AS WSTRING PTR, BYVAL b AS WSTRING PTR) AS LONG
FUNCTION = wcscmp(a, b)
END FUNCTION
DIM rg(5) AS CWSTR = {"Zorro", "Alex", "Celine", "Bill", "Forest", "Dexter"}
qsort @rg(0), 6, 544, CPTR(ANY PTR, @AfxCWstrCompare)
1) How do I get the size of the class? Currently, it is 544 bytes (when using the 64-bit compiler), but this may change if I modify the code.
2) qsort does the sorting correctly, but after calling it, the programs GPFs when the array goes out of scope and the destructor for each CWSTR is called.
Classes are just TYPE's so you should be able to use LEN or SIZEOF to get the size?
No. LEN and SIZEOF only returns the size of the variables used, as if it was a type without functions, not the total size allocated for an instance of it. A type with functions is not longer a type, but a class.
Jose,
This seems to work. Do you see any problems?
James
'==============================================================================
#define unicode
#define _WIN32_WINNT &h0602
#include Once "windows.bi"
#include Once "Afx/AfxStr.inc"
'==============================================================================
Private Sub QuickSort OVERLOAD (ArrayToSort() As CWSTR)
Dim As CWStr Temp
Dim As Long First, Last, i, j, StackPtr,StartEl,NumEls
StartEl = LBound(ArrayToSort)
NumEls = (UBound(ArrayToSort) - StartEl) + 1
Redim As Long QStack(NumEls \ 5 + 10)
First = StartEl
Last = StartEl + NumEls - 1
Do
Do
Temp = ArrayToSort((Last + First) \ 2)
i = First
j = Last
Do
While ArrayToSort(i) < Temp ' Swap < for > to do in descending order
i = i + 1
Wend
While ArrayToSort(j) > Temp ' Swap > for < to do in descending order
j = j - 1
Wend
If i > j Then Exit Do
If i < j Then Swap ArrayToSort(i), ArrayToSort(j)
i = i + 1
j = j - 1
Loop While i <= j
If i < Last Then
QStack(StackPtr) = i
QStack(StackPtr + 1) = Last
StackPtr = StackPtr + 2
End If
Last = j
Loop While First < Last
If StackPtr = 0 Then Exit Do
StackPtr = StackPtr - 2
First = QStack(StackPtr)
Last = QStack(StackPtr + 1)
Loop
Erase QStack
End Sub
'==============================================================================
Dim As Long ff1,i,j
Dim As String sWord,sBuf,sList
Dim AS CWStr cws(1 To 395)
ff1 = FreeFile
Open "slist.txt" For Input As ff1
'Line Input #ff1,sList
Line Input #ff1,sList
Close #ff1
? AfxStrParseCount(sList)
For i = 395 To 1 Step -1
j += 1
cws(j) = AfxStrParse(sList,i)
Next
For i = 1 To 395
? cws(i)
Next
QuickSort(cws())
For i = 1 To 395
? cws(i)
Next
Sleep
I have been thinking about it and CWSTR have too much overhead (about 534 bytes each one) to be used efficiently in big arrays. It will be better to use safearrays. Writing a class for one dimensional safearrays is not too difficult, but as soon as I will post it, someone will ask about multidimensional safearrays...