frage zu _arraysort und bubblesort

  • hi,
    ich ahbe ein programm geschrieben, dass verschiedene statistische größen aus messwerten berechnet.
    leider erfolgt beim sortieren der einzelnen wesswerte ein fehler. zuerst dachte ich dass, es an _arraysort liegt. dementsprechend testete ich es mit einer bubblesortversion.
    beide sortierprozeduren funktionieren seperat, aber nciht in verbindung mit dem programm.

    Spoiler anzeigen
    [autoit]


    #include <ButtonConstants.au3>
    #include <EditConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <StaticConstants.au3>
    #include <WindowsConstants.au3>
    #Include <Array.au3>

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

    Opt ("GUIOnEventMode", 1)

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

    ;Global $q[999]

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

    #Region ### START Koda GUI section ### Form=E:\autoit\diagramm\auswertung.kxf
    $Form2 = GUICreate("Auswertung", 234, 311, 302, 218)
    $Group1 = GUICtrlCreateGroup("Auswertung", 0, 0, 233, 265)
    $Label1 = GUICtrlCreateLabel("Median", 8, 25, 39, 17)
    $Label2 = GUICtrlCreateLabel("geometr. Mittelwert", 8, 50, 93, 17)
    $Label3 = GUICtrlCreateLabel("arithmet. Mittelwert", 8, 75, 92, 17)
    $Label4 = GUICtrlCreateLabel("Modalwert", 8, 100, 53, 17)
    $Label5 = GUICtrlCreateLabel("Spannweite", 8, 140, 60, 17)
    $Label6 = GUICtrlCreateLabel("Varianz", 8, 165, 39, 17)
    $Label7 = GUICtrlCreateLabel("Standartabweichung", 8, 190, 102, 17)
    $Input1 = GUICtrlCreateInput("0", 140, 25, 73, 21)
    $Input2 = GUICtrlCreateInput("0", 140, 50, 73, 21)
    $Input3 = GUICtrlCreateInput("0", 140, 75, 73, 21)
    $Input4 = GUICtrlCreateInput("0", 140, 100, 73, 21)
    $Input5 = GUICtrlCreateInput("0", 140, 140, 73, 21)
    $Input6 = GUICtrlCreateInput("0", 140, 165, 73, 21)
    $Input7 = GUICtrlCreateInput("0", 140, 190, 73, 21)
    $Label8 = GUICtrlCreateLabel("Klasseneinteilung", 8, 215, 86, 17)
    $Label9 = GUICtrlCreateLabel("Klassenweite", 8, 240, 66, 17)
    $Input8 = GUICtrlCreateInput("0", 140, 215, 73, 21)
    $Input9 = GUICtrlCreateInput("0", 140, 240, 73, 21)
    GUICtrlCreateGroup("", -99, -99, 1, 1)
    $Button1 = GUICtrlCreateButton("Ok", 0, 272, 65, 33, 0)
    GUICtrlSetOnEvent ($Button1, "run_")
    GUISetOnEvent($GUI_EVENT_CLOSE, "exit_")
    GUISetState()
    #EndRegion ### END Koda GUI section ###

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

    While 1
    Sleep(125)
    WEnd

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

    Func exit_()
    Exit
    EndFunc

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

    Func run_()
    $n=IniRead("cache.ini", "Anzahl", "n", "0")
    $n1 = $n - 1
    Dim $w[$n], $q[$n], $z[$n]
    For $i = 0 to ($n - 1)
    $w[$i]=IniRead("cache_werte.ini", "Werte", "w" & $i, "0")
    Next
    ;_ArraySort($w)
    Do ; bubblesort
    For $i = 0 to ($n1 - 1)
    If $w[$i] > $w[$i + 1] Then
    _ArraySwap($w[$i + 1], $w[$i])
    $tausch = True
    EndIf
    Next
    $n1 = $n1 - 0.25
    Until $n1 = 0
    _ArrayDisplay($w)
    $i = 0
    Do
    IniWrite("cache_werte_sortiert.ini", "Werte", "w" & $i, $w[$i])
    $i = $i + 1
    Until $i = $n
    $h = $n / 2

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

    If $h = Int($h) Then ;median
    $h1 = $h + 1
    $m = ($w[$h] + $w[$h1]) / 2
    GUICtrlSetData($Input1, $m)
    IniWrite("auswertung.ini", "Ergebnisse", "Median" , $m)
    Else
    $h2 = $h + 0.5
    GUICtrlSetData($Input1, $w[$h2])
    IniWrite("auswertung.ini", "Ergebnisse", "Median" , $w[$h2])
    EndIf

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

    $s = 0
    For $i = 0 to ($n - 1) ; quadrat mittelwert
    $q[$i] = $w[$i] * $w[$i]
    $s = $s + $q[$i]
    Next
    $m2 = Sqrt($s / $n)
    $m2 = Round($m2, 3)
    GUICtrlSetData($Input2, $m2)
    IniWrite("auswertung.ini", "Ergebnisse", "quadrat. Mittelwert" , $m2)

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

    $s = 0
    For $i = 0 to ($n - 1) ; mittelwert
    $s = $s + $w[$i]
    Next
    $m1 = $s/$n
    $m1 = Round($m1, 3)
    GUICtrlSetData($Input3, $m1)
    IniWrite("auswertung.ini", "Ergebnisse", "Mittelwert" , $m1)

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

    For $i = 0 to ($n - 1); modalwert
    $q[$i] = $w[$i]
    Next
    $i = 0
    $j = 0
    Do
    Do
    If $w[$i] = $q[$j] Then ; erstellen eines arrays z, das die häufigkeit der elemente in w angibt
    $z[$j] = $z[$j] + 1
    ; MsgBox(0, "", $i & ", " & $j) ;Indexkontrolle
    Else
    $z[$i] = 0
    EndIf
    If $j = ($n - 1) Then
    $j = 0
    EndIf
    $j = $j + 1
    Until $j = ($n - 1)
    $i = $i + 1
    Until $i = $n
    $j = 0
    $max = _ArrayMax($z) ;maximale anzahl der modularwerte
    For $i = 0 to ($n - 1)
    If $z[$i] = $max Then
    $j = $j + 1
    IniWrite("cache.ini", "Modalwert", "mod" & $j, $i)
    EndIf
    Next
    Dim $mod[$j +1], $mod_[$j]
    For $i = 1 To $j
    $mod[$i] = IniRead("cache.ini", "Modalwert", "mod" & $i, 0)
    Next
    _ArrayDelete($mod, 0)
    For $i = 0 To ($j - 1)
    $mod_[$i] = IniRead("cache_werte_sortiert.ini", "Werte", "w" & $mod[$i], 0)
    IniWrite("auswertung.ini", "Ergebnisse", "Modalwert" & ($i + 1) , $mod_[$i])
    Next
    Dim $b
    ;_ArrayDisplay($mod_)
    For $i = 0 To ($j - 1)
    $b = $b & "; " & $mod_[$i]
    Next
    GUICtrlSetData($Input4, $b)

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

    $spann = $w[0] - $w[$n-1] ; spannweite
    $spann = sqrt($spann * $spann)
    $spann = Round($spann, 3)
    GUICtrlSetData($Input5, $spann)
    IniWrite("auswertung.ini", "Ergebnisse", "Spannweite" , $spann)
    $s1 = 0
    For $i = 0 To ($n - 1) ; varianz
    $h1 = $w[$i] - $m1
    $s1 = $s1 + $h1 * $h1
    Next
    $var = $s1 / ($n - 1)
    $var = Round($var, 3)
    GUICtrlSetData($Input6, $var)
    IniWrite("auswertung.ini", "Ergebnisse", "Varianz" , $var)

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

    $sabw = Sqrt($var) ; standartabweichung
    $sabw = Round($sabw, 3)
    GUICtrlSetData($Input7, $sabw)
    IniWrite("auswertung.ini", "Ergebnisse", "Standartabweichung" , $sabw)

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

    $klas = Sqrt($n) ; klasseneinteilung
    If $klas < 6 Then
    $klas = 6
    GUICtrlSetData($Input8, $klas)
    IniWrite("auswertung.ini", "Ergebnisse", "Klasseneinteilung" , $klas)
    ElseIf $klas > 12 Then
    $klas = 12
    GUICtrlSetData($Input8, $klas)
    IniWrite("auswertung.ini", "Ergebnisse", "Klasseneinteilung" , $klas)
    Else
    $klas = Round($klas)
    GUICtrlSetData($Input8, $klas)
    IniWrite("auswertung.ini", "Ergebnisse", "Klasseneinteilung" , $klas)
    EndIf

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

    $weite = $spann / $klas ; klassenweite
    $weite = Round($weite, 3)
    GUICtrlSetData($Input9, $weite)
    IniWrite("auswertung.ini", "Ergebnisse", "Klassenweite" , $weite)
    EndFunc

    [/autoit]

    betreffende programmzeilen (49 ... 64)

    Spoiler anzeigen
    [autoit]


    $n=IniRead("cache.ini", "Anzahl", "n", "0")
    $n1 = $n - 1
    Dim $w[$n], $q[$n], $z[$n]
    For $i = 0 to ($n - 1)
    $w[$i]=IniRead("cache_werte.ini", "Werte", "w" & $i, "0")
    Next
    ;_ArraySort($w)
    Do ; bubblesort
    For $i = 0 to ($n1 - 1)
    If $w[$i] > $w[$i + 1] Then
    _ArraySwap($w[$i + 1], $w[$i])
    $tausch = True
    EndIf
    Next
    $n1 = $n1 - 0.25
    Until $n1 = 0

    [/autoit]

    cache.ini

    Code
    [Anzahl]
    n=6
    [Modalwert]
    mod1=1


    cache_werte.ini

    Code
    [Werte]
    w0=5
    w1=5
    w2=5
    w3=5
    w4=10
    w5=7

    cache_werte_sortiert.ini

    Code
    [Werte]
    w0=10
    w1=5
    w2=5
    w3=5
    w4=5
    w5=7

    weiß jmd woran dies liegen könnte?

    mfg bocky

    Einmal editiert, zuletzt von bocky3 (29. Juli 2009 um 12:51)

  • Hallo,
    du solltest auch sortieren in deinem selbstgeschriebenen Algorithmus!
    Zzt "sortierst" (tauscht) du nur die gerade gelesene mit der nächsten Zahl. d.h. ist deine aktuelle Zahl kleiner wie die [$i-5] z.B., dann ist das deinem "Algorithmus" egal. Eine zweite Schleife muss her^^
    Aber was funktioniert nicht an arraysort() ?

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>
    Dim $array1[10] = [233, 45, 67, 78, 299, 12, 91, 45, 57, 0]
    $array2 = $array1
    $array3 = $array1

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

    MsgBox(0, 0, "Array1", 2)
    _ArrayDisplay($array1)

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

    MsgBox(0, 0, "Array1 aufsteigend sortiert", 2)
    _ArraySort($array1)
    _ArrayDisplay($array1)

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

    MsgBox(0, 0, "Array1 absteigend sortiert", 2)
    _ArraySort($array2, 1)
    _ArrayDisplay($array2)

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

    ;zu fuss....
    $aufsteigend = MsgBox(4, 0, "Array1 aufsteigend sortieren?")
    For $i = 0 To UBound($array3) - 1
    For $w = 0 To UBound($array3) - 1
    If $aufsteigend = 6 Then
    If $array3[$w] > $array3[$i] Then _ArraySwap($array3[$w], $array3[$i])
    Else
    If $array3[$w] <= $array3[$i] Then _ArraySwap($array3[$w], $array3[$i])
    EndIf
    Next
    Next
    _ArrayDisplay($array3)

    [/autoit]
  • bubblesort ist sortieren mit austauschen.
    es ist eine gekoppelte schleife. der algorithmus, den ich verwendete, funktioniert.

    Spoiler anzeigen
    Zitat

    Bubblesort gehört zur Klasse der In-place-Verfahren, was bedeutet, dass der Algorithmus zum Sortieren keinen zusätzlichen Arbeitsspeicher außer den lokalen Laufvariablen der Prozedur benötigt. Dadurch, dass grundsätzlich nur aneinandergrenzende Elemente miteinander vertauscht werden, eignet sich dieses Verfahren auch zum Sortieren von Listen mit unterschiedlich großen Elementen. (Wikipedia)


    hier mal entkoppelt:

    Spoiler anzeigen
    [autoit]


    #Include <Array.au3>
    HotKeySet("{F4}", "sort")
    Global $n = 21, $w[$n + 1]

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

    While 1
    Sleep(125)
    WEnd

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

    Func sort()
    For $i = 0 To ($n - 1)
    $w[$i] = $i
    Next
    _ArrayReverse($w)
    _ArrayDisplay($w)
    bubble_sort()
    _ArrayDisplay($w)
    Exit
    EndFunc

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

    Func bubble_sort()
    Do
    For $i = 0 to ($n - 1)
    If $w[$i] > $w[$i + 1] Then
    _ArraySwap($w[$i + 1], $w[$i])
    EndIf
    Next
    $n = $n - 1
    Until $n = 1
    EndFunc

    [/autoit]

    sieh dir sortierte liste an: w0 = 10
    selbes resultat mit bubblesort und _arraysort.

  • Zitat

    selbes resultat mit bubblesort und _arraysort.

    Naja, dein bubblesort() ist definitiv FALSCH. Daher kann das Ergebnis nicht stimmen, ändere mal in Zeile 22 von ($n-1) in ($n-2), deine Indizierung stimmt vorne und hinten nicht.
    bsp:

    [autoit]

    dim $a[3]=[1,2,3]

    [/autoit]


    dann ist a[0]=1, a[1]=2 und a[2]=3
    somit ist n=2 !!! und nicht 3....

    [autoit]

    ubound()

    [/autoit]

    ist dein Freund...

    Spoiler anzeigen
    [autoit]

    #Include <Array.au3>
    HotKeySet("{F4}", "sort")

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

    dim $w[10]=[3,5,7,9,8,6,4,4,1,0]
    global $n=10

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

    While 1
    Sleep(125)
    WEnd

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

    Func sort()
    _ArrayDisplay($w)
    bubble_sort()
    _ArrayDisplay($w)
    Exit
    EndFunc

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

    Func bubble_sort()
    Do
    For $i = 0 to ($n - 2)
    If $w[$i] > $w[$i + 1] Then
    _ArraySwap($w[$i + 1], $w[$i])
    EndIf
    Next
    $n = $n - 1
    Until $n = 1
    EndFunc

    [/autoit]

    ...so gehts...besser ist aber immer in den Schleifen bis ubound()-1 zu zählen, in deinem speziellen Fall ist es aber ubound()-1-1, du vergleichst ja mit einem $i+1...

    Zitat

    der algorithmus, den ich verwendete, funktioniert.

    ...nach Änderungen jetzt auch ohne Fehler ;)

  • Das Problem bei deinem Programm ist, dass du die Werte mit IniRead einliest. Dabeik werden Zahlen als Strings gelesen, was in _ArraySort dazu führt, dass nach Strings sortiert wird und nicht nach Zahlen. Beim Einlesen musst du also die Strings in Zahlen umwandeln:

    [autoit]

    $n = IniRead("cache.ini", "Anzahl", "n", "0")
    Dim $w[$n], $q[$n], $z[$n]
    For $i = 0 to ($n - 1)
    $w[$i]= Number(IniRead("cache_werte.ini", "Werte", "w" & $i, 0))
    Next
    _ArraySort($w)

    [/autoit]
  • entschuldigt, dass die antwort so lange auf sich warten lies, ich hatte prüfungen und noch einige andere dinge zu tun.

    danke progandy, deine version funktioniert.
    ich nahm fälschlicherweise an, dass autoit zahlen automatisch als zahlen einliest.

    in hinsicht auf das gesamte programm, ist ubound nicht mein freund.