Results 1 to 9 of 9

Thread: Function: Return a sorted string

  1. #1

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2002
    Location
    Fox, OK
    Posts
    381

    Function: Return a sorted string

    I need a function that will return a string with the characters sorted.
    For example, if I send the function "exam" it should return "aemx".
    Does this already exist in VB6?

  2. #2
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    Re: Function: Return a sorted string

    No, it doesn't.

    Does case matter?

  3. #3

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2002
    Location
    Fox, OK
    Posts
    381

    Re: Function: Return a sorted string

    This is what I did and it works but I feel like I'm missing something simple.

    vb Code:
    1. Public Function SortWord(w$)
    2. 'This function receives a word and returns the word with the letters sorted
    3.     Dim inner As Integer, outer As Integer, ln As Integer, tmp$, c$(1 To 20), i As Integer
    4.     ln = Len(w$)
    5.     For i = 1 To ln
    6.         c$(i) = Mid$(w$, i, 1)
    7.     Next i
    8.    
    9.     For outer = 1 To ln
    10.         For inner = 1 To ln
    11.             If c$(outer) < c$(inner) Then
    12.                 tmp$ = c$(outer)
    13.                 c$(outer) = c$(inner)
    14.                 c$(inner) = tmp$
    15.             End If
    16.         Next inner
    17.     Next outer
    18.    
    19.     tmp$ = ""
    20.     For i = 1 To Len(w$)
    21.         tmp$ = tmp$ + c$(i)
    22.     Next i
    23.    
    24.     SortWord = tmp$
    25. End Function

  4. #4
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    Re: Function: Return a sorted string

    If you expect the strings to be small, like say less than 100 characters, insertion sort is probably fine.
    Code:
    Public Function SortString(pstrString As String) As String
        Dim strArray() As String
        Dim i As Long
        
        ReDim strArray(Len(pstrString) - 1)
        For i = 1 To Len(pstrString)
            strArray(i - 1) = Mid$(pstrString, i, 1)
        Next
        InsertionSort1 strArray
        SortString = Join(strArray, "")
    End Function
    
    Public Sub InsertionSort1(ByRef pvarArray As Variant)
        Dim i As Long
        Dim j As Long
        Dim iMin As Long
        Dim iMax As Long
        Dim varSwap As Variant
        
        iMin = LBound(pvarArray) + 1
        iMax = UBound(pvarArray)
        For i = iMin To iMax
            varSwap = pvarArray(i)
            For j = i To iMin Step -1
                If varSwap < pvarArray(j - 1) Then pvarArray(j) = pvarArray(j - 1) Else Exit For
            Next j
            pvarArray(j) = varSwap
        Next i
    End Sub
    If the strings could be very long, it would be much more efficient to use counting sort.

  5. #5
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    Re: Function: Return a sorted string

    Here's a quick pass at counting sort. It works, but it's case sensitive, and it can't be made to ignore case by simply putting it in a module with Option Compare Text. (The above solution with insertion sort can.)
    Code:
    Public Function SortString(pstrString As String) As String
        Dim lngCount(255) As Long
        Dim bytArray() As Byte
        Dim i As Long
        Dim j As Long
        Dim k As Long
        
        bytArray = StrConv(pstrString, vbFromUnicode)
        For i = 0 To UBound(bytArray)
            lngCount(bytArray(i)) = lngCount(bytArray(i)) + 1
        Next
        i = 0
        For j = 0 To 255
            For k = 1 To lngCount(j)
                bytArray(i) = j
                i = i + 1
            Next
        Next
        SortString = StrConv(bytArray, vbUnicode)
    End Function
    As you might notice, there isn't a single comparison in this code. That's because counting sort isn't a comparison algorithm, meaning it isn't constrained by the limits for them. Given a sufficiently large string, this will blow the fastest comparison sorts like quicksort out of the water.
    Last edited by Ellis Dee; May 11th, 2009 at 10:54 PM.

  6. #6

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2002
    Location
    Fox, OK
    Posts
    381

    Re: Function: Return a sorted string

    My code will not need to sort more than 10 or 11 characters most likely. So which one would be best? Or does it even matter on something that small?

  7. #7
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    Re: Function: Return a sorted string

    For 10 or 11 elements, it doesn't really matter. Conventional wisdom is that insertion sort is best for small lists, so may as well go with that. Unless you're sending thousands of strings to be sorted in a loop, the difference between the best and worst algorithm won't be measurable.

    That counting sort I posted isn't so hot because it uses ASCII order, which to a large extent is random. Here's a better one, though the added overhead probably makes it none too fast for such short strings. For a billion or so characters, this may be as fast as it gets:
    Code:
    Public Function SortString(ByVal pstrString As String) As String
        Const CharMap = """ !#$&#37;&()*,./:;?@[\]^ˆ_`{|}~&#161;&#166;&#168;&#175;&#180;&#184;&#191;˜‘’‚“”„‹›+<=>&#177;&#171;&#187;&#215;&#247;&#162;&#163;&#164;&#165;&#167;&#169;&#172;&#174;&#176;&#181;&#182;&#183;†‡•…‰€0&#188;&#189;&#190;1&#185;2&#178;3&#179;456789Aa&#170;&#193;&#225;&#192;&#224;&#194;&#226;&#196;&#228;&#195;&#227;&#197;&#229;&#198;&#230;BbCc&#199;&#231;Dd&#208;&#240;Ee&#201;&#233;&#200;&#232;&#202;&#234;&#203;&#235;FfƒGgHhIi&#205;&#237;&#204;&#236;&#206;&#238;&#207;&#239;JjKkLlMmNn&#209;&#241;Oo&#186;&#211;&#243;&#210;&#242;&#212;&#244;&#214;&#246;&#213;&#245;&#216;&#248;ŒœPpQqRrSsŠš&#223;Tt&#222;&#254;™Uu&#218;&#250;&#217;&#249;&#219;&#251;&#220;&#252;VvWwXxYy&#221;&#253;Ÿ&#255;ZzŽž"
        Dim lngCount() As Long
        Dim lngIndex As Long
        Dim i As Long
        Dim j As Long
        Dim k As Long
        
        ReDim lngCount(Len(CharMap))
        For i = 1 To Len(pstrString)
            lngIndex = InStr(CharMap, Mid$(pstrString, i, 1))
            lngCount(lngIndex) = lngCount(lngIndex) + 1
        Next
        i = 0
        For j = 1 To Len(CharMap)
            For k = 1 To lngCount(j)
                i = i + 1
                Mid$(pstrString, i, 1) = Mid$(CharMap, j, 1)
            Next
        Next
        SortString = pstrString
    End Function
    It's still not ideal because it doesn't handle 40 or so unprintable characters. The most complete solution would be to create CharMap dynamically with all 255 chars, sort it with InsertionSort, and then run counting sort with that.

    Obviously that's a huge amount of overhead, which is why I didn't bother posting it.

  8. #8

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2002
    Location
    Fox, OK
    Posts
    381

    Re: Function: Return a sorted string

    Thanks for the effort. I guess I'll just stick with what I wrote. I know it works fine.

  9. #9
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    Re: Function: Return a sorted string

    I'd go with the insertion sort solution, but if you want to stick with what you have, the following changes will make it much, much faster:
    Code:
        For outer = 1 To ln
            For inner = ln To outer Step -1
                If c$(outer) > c$(inner) Then
                    tmp$ = c$(outer)
                    c$(outer) = c$(inner)
                    c$(inner) = tmp$
                End If
            Next inner
        Next outer

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width