Jump to content
Sign in to follow this  
Albertxu

How to sort all words by alphabet in a word list?

Recommended Posts

Anyone fancy trying this in some language other than English?

Probably stupic though.

Hi - I'm happy.

It sorts it better than _ArraySort except for numbers. But then again the languages I'm capable of does not have any letters above ASCII 122.

#include <Array.au3>
$string = "10 chicken abC aBc cheese Chocolate chalk Abc 9 Ikhanda Kop"
$aArray = StringSplit($string," ", 3)
_ArraySort($aArray)
_ArrayDisplay($aArray, "Normal Sort")
For $i = 0 To UBound($aArray) -1
    $aArray[$i] = StringToBinary($aArray[$i])
Next
_ArraySort($aArray)
For $i = 0 To UBound($aArray) -1
    $aArray[$i] = BinaryToString($aArray[$i])
Next
_ArrayDisplay($aArray, "Binary Sort")

So maybe a ascii sorter?


Share this post


Link to post
Share on other sites

There are different methods. I suggest to begin with that you look at the helpfile example for _ArrayAdd. This shows the easiest method to start with. Don't worry about using the function _ArrayAdd. Just look at how the array is declared. To offer a brief explanation:

First an array containing 10 elements is declared using the keyword Local. Then each element is given a value (in this case a name). Notice that the first element is counted as element 0. Run the script and try making some alterations to it.

Edit

Another method would be to use _FileReadToArray. This may suit your purpose more readily, however I strongly advise that you familiarize yourself with the first method I mentioned also.

So I used _FileReadToArray to load those words as Array. But How can I write those sorted words out in a result.txt file? I used FileWriteLine but did not succeed.

#include <Array.au3>
#include <file.au3>
Dim $aRecords
If Not _FileReadToArray("random.txt",$aRecords) Then
   MsgBox(4096,"Error", " Error reading log to Array     error:" & @error)
   Exit
EndIf

_arraysort($aRecords)
;_ArrayDisplay($aRecords)
FileWriteLine("result.txt",$aRecords)

Share this post


Link to post
Share on other sites

[/autoit]I see that (my) nighttime has been busy here.

AutoIt natively offers StringCompare to sort strings according to your system/user locale settings when this function is used with option 0.
So if your locale settings is Swedish-Finland, it will sort string according to the [b]sv-fi[/b] Unicode locale, while if your locale is Swedish-Sweden it will use [b]sv-se[/b] collation rules.
As a consequence of being language-aware, StringCompare can give the surprising result that strings not having the same length (in Unicode characters) compare equal.  For instance, using my fr-FR locale:
[autoit]Local $s1 = 'baffled', $s2 = 'baffled'
ConsoleWrite(StringLen($s1) & ' =?= ' & StringLen($s2) & @LF)
ConsoleWrite(Stringcompare($s1, $s2, 0) & @LF)
ConsoleWrite(Stringcompare($s1, $s2, 1) & @LF)
ConsoleWrite(Stringcompare($s1, $s2, 2
returns:
7 =?= 5
0
-1
-1
This is due to the 'ffl' ligature (only one char) used in $s2 being expanded to 'ffl' (three chars) by my frenchy locale (may for english as well, didn't check).

BTW a locale doesn't only affect string collation, but also times, dates, numbers, ... representation and format, hyphenation, and much much more.

Actual nightmare begins when you need to collate strings from various languages.

@JohnOne, JoHanatCent,

What you propose doesn't hold water. Here's why: StringToBinary will first convert the Unicode string to ANSI using your current locale setting, turning any Unicode character not available in your codepage into a question mark. Then it will return that sequence of bytes for you to sort. It makes for a poor English-7bit-ASCII-only sort with very limited use. Use StringCompare with the option you need.


This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites

Ha! I was under a vague impression I was mixing things somewhere but didn't have much time to check what. In fact I need to use several modified versions of _ArraySort for specific purposes and forgot exactly what was the native function doing. Thanks for the head up, I'll edit my misguided post. Indeed, _ArraySort uses StringCompare with option 0 (case insensitive, using locale).

@czardas,

What you experience in your post #13 is that the collation (comparison function) is case insensitive. This is not to be confused with the stability of the sort function. _ArraySort() uses one or two sort algorithms: quicksort and insertion sort, the former being unstable contrary to the latter, which means that it may change the initial order of sort keys that are found equal. Since the inner compare function is case insensitive, it may order B before or after b (without that being a bug). Most implementations of the quicksort algorithm are unstable, but when the input array (or a subarray at some level) has less than 15 entries, _ArraySort switches to an insertion sort, which is stable. Readers interested in sorting algorithms and their characteristics and tradeoffs should google around.


This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites

Everyone seems to have forgoten about the sort code written by Siao

;===============================================================================
; Function Name:    _ArraySortClib() v4
; Description:         Sort 1D/2D array using qsort() from C runtime library
; Syntax:
; Parameter(s):      $Array - the array to be sorted, ByRef
;                    $iMode - sort mode, can be one of the following:
;                        0 = numerical, using double precision float compare
;                        1 = string sort, case insensitive (default)
;                        2 = string sort, case sensitive
;                        3 = word sort, case insensitive - compatible with AutoIt's native compare
;                    $fDescend - sort direction. True = descending, False = ascending (default)
;                    $iStart - index of starting element (default 0 = $array[0])
;                    $iEnd - index of ending element (default 0 = Ubound($array)-1)
;                    $iColumn - index of column to sort by (default 0 = first column)
;                    $iStrMax - max string length of each array element to compare (default 4095 chars)
; Requirement(s):    msvcrt.dll (shipped with Windows since Win98 at least), 32-bit version of AutoIt
; Return Value(s):    Success = Returns 1
;                    Failure = Returns 0 and sets error:
;                        @error 1 = invalid array
;                        @error 2 = invalid param
;                        @error 3 = dll error
;                        @error 64 = 64-bit AutoIt unsupported
; Author(s):   Siao
; Modification(s):
;===============================================================================

Func _ArraySortClib(ByRef $Array, $iMode = 1, $fDescend = False, $iStart = 0, $iEnd = 0, $iColumn = 0, $iStrMax = 4095)
  If @AutoItX64 Then Return SetError(64, 0, 0)
  Local $iArrayDims = UBound($Array, 0)
  If @error Or $iArrayDims > 2 Then Return SetError(1, 0, 0)
  Local $iArraySize = UBound($Array, 1), $iColumnMax = UBound($Array, 2)
  If $iArraySize < 2 Then Return SetError(1, 0, 0)
  If $iEnd < 1 Or $iEnd > $iArraySize - 1 Then $iEnd = $iArraySize - 1
  If ($iEnd - $iStart < 2) Then Return SetError(2, 0, 0)
  If $iArrayDims = 2 And ($iColumnMax - $iColumn < 0) Then Return SetError(2, 0, 0)
  If $iStrMax < 1 Then Return SetError(2, 0, 0)
  Local $i, $j, $iCount = $iEnd - $iStart + 1, $fNumeric, $aRet, $sZero = ChrW(0), $sStrCmp, $sBufType = 'byte[', $hDll = DllOpen('msvcrt.dll'), $tSource, $tIndex, $tFloatCmp, $tCmpWrap = DllStructCreate('byte[64]'), $tEnumProc = DllStructCreate('byte[64]')
  If $hDll = -1 Then Return SetError(3, 0, 0)
  ;; initialize compare proc
  Switch $iMode
    Case 0
      $fNumeric = True
      $tFloatCmp = DllStructCreate('byte[36]')
      DllStructSetData($tFloatCmp, 1, '0x8B4C24048B542408DD01DC1ADFE0F6C440750D80E441740433C048C333C040C333C0C3')
      DllStructSetData($tCmpWrap, 1, '0xBA' & Hex(Binary(DllStructGetPtr($tFloatCmp)), 8) & '8B4424088B4C2404FF30FF31FFD283C408C3')
      DllStructSetData($tEnumProc, 1, '0x8B7424048B7C24088B4C240C8B442410893789470483C60883C708404975F1C21000')
    Case 1,2
      $sStrCmp = "_strcmpi" ;case insensitive
      If $iMode = 2 Then $sStrCmp = "strcmp" ;case sensitive
      $aRet = DllCall('kernel32.dll','ptr','GetModuleHandle', 'str','msvcrt.dll')
      $aRet = DllCall('kernel32.dll','ptr','GetProcAddress', 'ptr',$aRet[0], 'str',$sStrCmp)
      If $aRet[0] = 0 Then Return SetError(3, 0, 0*DllClose($hDll))
      DllStructSetData($tCmpWrap, 1, '0xBA' & Hex(Binary($aRet[0]), 8) & '8B4424088B4C2404FF30FF31FFD283C408C3')
      DllStructSetData($tEnumProc, 1, '0x8B7424048B7C24088B4C240C8B542410893789570483C7088A064684C075F9424975EDC21000')
    Case 3
      $sBufType = 'wchar['
      $aRet = DllCall('kernel32.dll','ptr','GetModuleHandle', 'str','kernel32.dll')
      $aRet = DllCall('kernel32.dll','ptr','GetProcAddress', 'ptr',$aRet[0], 'str','CompareStringW')
      If $aRet[0] = 0 Then Return SetError(3, 0, 0*DllClose($hDll))
      DllStructSetData($tCmpWrap, 1, '0xBA' & Hex(Binary($aRet[0]), 8) & '8B4424088B4C24046AFFFF306AFFFF3168010000006800040000FFD283E802C3')
      DllStructSetData($tEnumProc, 1, '0x8B7424048B7C24088B4C240C8B542410893789570483C7080FB70683C60285C075F6424975EAC21000')
    Case Else
      Return SetError(2, 0, 0)
  EndSwitch
  ;; write data to memory
  If $fNumeric Then
    $tSource = DllStructCreate('double[' & $iCount & ']')
    If $iArrayDims = 1 Then
      For $i = 1 To $iCount
        DllStructSetData($tSource, 1, $Array[$iStart + $i - 1], $i)
      Next
    Else
      For $i = 1 To $iCount
        DllStructSetData($tSource, 1, $Array[$iStart + $i - 1][$iColumn], $i)
      Next
    EndIf
  Else
    Local $sMem = ""
    If $iArrayDims = 1 Then
      For $i = $iStart To $iEnd
        $sMem &= StringLeft($Array[$i],$iStrMax) & $sZero
      Next
    Else
      For $i = $iStart To $iEnd
        $sMem &= StringLeft($Array[$i][$iColumn],$iStrMax) & $sZero
      Next
    EndIf
    $tSource = DllStructCreate($sBufType & StringLen($sMem) + 1 & ']')
    DllStructSetData($tSource, 1, $sMem)
    $sMem = ""
  EndIf
  ;; index data
  $tIndex = DllStructCreate('int[' & $iCount * 2 & ']')
  DllCall('user32.dll','uint','CallWindowProc', 'ptr',DllStructGetPtr($tEnumProc), 'ptr',DllStructGetPtr($tSource), 'ptr',DllStructGetPtr($tIndex), 'int',$iCount, 'int',$iStart)
  ;; sort
  DllCall($hDll,'none:cdecl','qsort', 'ptr',DllStructGetPtr($tIndex), 'int',$iCount, 'int',8, 'ptr',DllStructGetPtr($tCmpWrap))
  DllClose($hDll)
  ;; rearrange the array by sorted index
  Local $aTmp = $Array, $iRef
  If $iArrayDims = 1 Then ; 1D
    If $fDescend Then
      For $i = 0 To $iCount - 1
        $iRef = DllStructGetData($tIndex, 1, $i * 2 + 2)
        $Array[$iEnd - $i] = $aTmp[$iRef]
      Next
    Else ; ascending
      For $i = $iStart To $iEnd
        $iRef = DllStructGetData($tIndex, 1, ($i - $iStart) * 2 + 2)
        $Array[$i] = $aTmp[$iRef]
      Next
    EndIf
  Else ; 2D
    If $fDescend Then
      For $i = 0 To $iCount - 1
        $iRef = DllStructGetData($tIndex, 1, $i * 2 + 2)
        For $j = 0 To $iColumnMax - 1
          $Array[$iEnd - $i][$j] = $aTmp[$iRef][$j]
        Next
      Next
    Else ; ascending
      For $i = $iStart To $iEnd
        $iRef = DllStructGetData($tIndex, 1, ($i - $iStart) * 2 + 2)
        For $j = 0 To $iColumnMax - 1
          $Array[$i][$j] = $aTmp[$iRef][$j]
        Next
      Next
    EndIf
  EndIf
  Return 1
EndFunc   ;<==> _ArraySortClib()

George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Share this post


Link to post
Share on other sites

Very nice.

Something I wasn't aware of is that the native StringCompare uses a word sort!

The direct consequence can be misleading to unsuspecting users:

#include <Array.au3>

Local $a[224][2]
For $i = 0 To 223
    $a[$i][0] = Chr($i + 0x20)
Next

_ArraySort($a)

For $i = 0 To 223
    $a[$i][1] = Chr($i + 0x20)
Next
_ArrayDisplay($a)
Depending on your application and typical string contents, it may be a good or terrible thing.

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites

@czardas

The issue (or non-issue depending of your point of view) is that the holly ASCII order is not conserved by this collation, as the example code just above shows.


This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...