Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Alphabetizing Anyone?
#1
Happy holidays. I've sniffed around the site and can't find an alphabetizing routine. I doesn't have to be fast - I just need it to reorder some short files holding song titles. Any ideas for a guy looking for a simple sorter?  Thanks!
Reply
#2
I recommend _Memsort, if possible:  https://qb64phoenix.com/forum/showthread.php?tid=75

Works on everything pretty much *except* variable length strings.  (_Mem doesn't support variable length strings.)

If you need a variable string sort instead, just let me know.  I've got several of all shapes and models sitting around here in various places.  Wink
Reply
#3
(12-20-2023, 06:17 PM)SMcNeill Wrote: I recommend _Memsort, if possible:  https://qb64phoenix.com/forum/showthread.php?tid=75

Works on everything pretty much *except* variable length strings.  (_Mem doesn't support variable length strings.)

If you need a variable string sort instead, just let me know.  I've got several of all shapes and models sitting around here in various places.  Wink
Excellent, Steve. Thanks, I'll check it out.
Reply
#4
And for variable length strings in an array called sa$() (sa=String Array):
Code: (Select All)
DefLng A-Z
Const nItems = 1000000
ReDim Shared sa$(1 To nItems) 'setup with string array sa$() shared so dont have to pass as parameter
For x = 1 To nItems ' make a random list to sort
    b$ = ""
    r = (Rnd * 5) \ 1 + 2
    For i = 0 To r
        b$ = b$ + Mid$("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.?", (Rnd * 64) \ 1 + 1, 1)
    Next
    sa$(x) = b$
    Print b$,
Next
Print
Print "Press any to sort"
Sleep
t## = Timer(.01)
QSort 1, nItems
time## = Timer(.01) - t##
Cls
For i = 1 To nItems
    Print sa$(i),
Next
Print
Print "time:"; time##


' modified for QB64 from JB
' This is the best all purpose sort routine around, don't worry how it works, it just does!
' To use this sub rountine store all the string values you want to sort into sa$() array
' call Qsort with Start = 1 and Finish = number of Items in your array
Sub QSort (Start, Finish) 'sa$ needs to be   DIM SHARED !!!!     array
    Dim i As Long, j As Long, x$
    i = Start
    j = Finish
    x$ = sa$(Int((i + j) / 2))
    While i <= j
        While sa$(i) < x$
            i = i + 1
        Wend
        While sa$(j) > x$
            j = j - 1
        Wend
        If i <= j Then
            Swap sa$(i), sa$(j)
            i = i + 1
            j = j - 1
        End If
    Wend
    If j > Start Then QSort Start, j
    If i < Finish Then QSort i, Finish
End Sub
b = b + ...
Reply
#5
Awesome. Thanks, bplus!
Reply
#6
Code: (Select All)
ReDim Shared sa$(1 To nItems) 'setup with string array sa$() shared so dont have to pass as parameter

What if the user requires two string arrays to sort, and cannot copy or tamper with the only "sa$()" one?

I'd rather take the example in QB64 Wiki, as slow and clunky as it might look.

https://qb64phoenix.com/qb64wiki/index.php/SWAP

(Example #3 but change array type to string.)
Reply
#7
If I was still trying to peddle PowerShell scripts, I'd say use a text file and have PowerShell sort it for you and put it into a sorted file to be read. Or, use a file and have PowerShell output to stdout and use pipecom to read it in.
Tread on those who tread on you

Reply
#8
When I have a small list of strings to sort I usually use this simple bubble sort. It's not fast but with small arrays of strings it's not even noticeable.

Code: (Select All)
'simple bubble sort

DIM Outer AS LONG '             outer loop counter
DIM Inner AS LONG '             inner loop counter
DIM StringList(100) AS STRING ' an array of strings

FOR Outer = 1 TO UBOUND(StringList) - 1 '                                   loop array size-1
    FOR Inner = 1 TO UBOUND(stringlist) - Outer '                           loop remaining indexes
        IF UCASE$(StringList(Inner)) > UCASE$(StringList(Inner + 1)) THEN ' is next index smaller?
            SWAP StringList(Inner), StringList(Inner + 1) '                 yes, swap indexes (bubble up)
        END IF
    NEXT Inner
NEXT Outer
New to QB64pe? Visit the QB64 tutorial to get started.
QB64 Tutorial
Reply
#9
For working in PowerShell:
I have formatted them as if you are running it from inside a SHELL call in QB64. The carets (^) are needed to escape the pipe (|) characters. If you are running it already in PowerShell, you would get rid of "PowerShell -NoProfile" and the carets.

If you want the directory listing of all text files sorted (PowerShell):
Quote:PowerShell -NoProfile Get-ChildItem -Filter *.txt ^| Select Name -ExpandProperty Name ^| Sort-Object > sorted.txt

If you already have a file with content inside of it (PowerShell):
Quote:PowerShell -NoProfile Get-Content -Path examplefile.txt ^| Sort-Object > sorted.txt

P.S
The "-NoProfile" switch is necessary for PowerShell because there are profile scripts that are loaded when it is started that slow down execution considerably. "-NoProfile" tells it to ignore user settings which speeds up the call.

P.P.S
The redirect to sorted.txt is only necessary if you are not using pipecom. Without pipecom, you won't have access to the direct stdout handle. With it, you would remove that redirect and just grab the raw stdout from the call.
Tread on those who tread on you

Reply
#10
Thanks, Terry and Spriggsy.  Exclamation
Reply




Users browsing this thread: 1 Guest(s)