Sortieren mit eigener Vergleichsfunktion (UDF)

    • Offizieller Beitrag

    Hi,

    Sortieren funktioniert in AutoIt nicht so schön wie in manch anderer Sprache, weil Funktionen (bisher) keine übergebbaren Objekte sind.
    Allerdings kann man das mit Hilfe von Call ein Stück weit nachbauen. Sicher nicht effizient, aber an mancher Stelle wegen der hohen Ausdruckskraft sicher eine nützliche Lösung. Ob ich beim Umbau eines QuickSort-Algos von Wikipedia alles richtig gemacht habe, weiß ich nicht. Unit-Tests fehlen mir in AutoIt schon auch schmerzlich. Ich glaube, dass ich sogar schon mal einen Satz Funktionen dafür hochgeladen habe hier im Forum!? Egal…

    Code:

    Spoiler anzeigen
    [autoit]

    #cs ----------------------------------------------------------------------------

    [/autoit] [autoit][/autoit] [autoit]

    AutoIt Version: 3.3.9.0 (beta)
    Author: peethebee
    Date: 2012-06-10

    [/autoit] [autoit][/autoit] [autoit]

    Script Function:
    Sort using a (somewhat fake) comparator.

    [/autoit] [autoit][/autoit] [autoit]

    #ce ----------------------------------------------------------------------------

    [/autoit] [autoit][/autoit] [autoit]

    #include <Array.au3>
    ;~ #include "var_dump.au3"

    [/autoit] [autoit][/autoit] [autoit]

    Func _compSort(ByRef $array, $compFuncName = "_compBasic", $reverse = False, $left = 0, $right = -1)
    If $right == -1 Then $right = UBound($array) - 1
    Local $i = $left
    Local $j = $right
    Local $v = $array[Round(($left + $right) / 2, 0)]
    While $j > $i
    While $i < $right And Call($compFuncName, $array[$i], $v, $reverse) < 0
    $i = $i + 1
    WEnd
    While $j > $left And Call($compFuncName, $array[$j], $v, $reverse) > 0
    $j = $j - 1
    WEnd
    If $i <= $j and Call($compFuncName, $array[$i], $array[$j], $reverse) >= 0 Then
    _compSwap($array, $i, $j)
    $i = $i + 1
    $j = $j - 1
    EndIf
    WEnd
    If ($left < $j) Then _compSort($array, $compFuncName, $reverse, $left, $j)
    If ($right > $i) Then _compSort($array, $compFuncName, $reverse, $i, $right)
    EndFunc ;==>_compSort

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _compSwap(ByRef $array, $aIndex, $bIndex)
    Local $t = $array[$aIndex]
    $array[$aIndex] = $array[$bIndex]
    $array[$bIndex] = $t
    EndFunc ;==>_compSwap

    [/autoit] [autoit][/autoit] [autoit]

    Func _compBasic($a, $b, $reverse)
    If ($a > $b) and (Not $reverse) Then Return 1
    If ($a > $b) and ($reverse) Then Return -1
    If ($b > $a) and (Not $reverse) Then Return -1
    If ($b > $a) and ($reverse) Then Return 1
    Return 0
    EndFunc ;==>_compBasic

    [/autoit] [autoit][/autoit] [autoit]

    ; test
    ;~ Global $myarray[10] = [11,22,33,44,55,66,77,88,99,1010]
    ;~ _compSort($myarray, "_compBasic", True)
    ;~ var_dump_c($myarray, False, ", ")

    [/autoit]


    Johannes