Array nach rechts oder nach links schieben

  • Hi @all
    Der Titel sagt alles.

    Bsp:
    $array = [0,1,2,3]
    rechts=> $array = [3,0,1,2]
    links=> $array = [1,2,3,0]

    Thx für antwort im vorraus :D

    Nur keine Hektik - das Leben ist stressig genug

  • [autoit]

    Local $array[4] = [0,1,2,3]
    Local $rarray,$larray

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

    printArray($array)

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

    $rarray = shiftRight($array)
    printArray($rarray)

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

    $larray = shiftLeft($array)
    printArray($larray)

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

    Func printArray($array)
    For $i=0 To UBound($array)-1 Step 1
    ConsoleWrite($array[$i]&" ")
    Next
    ConsoleWrite(@CRLF&"-----------"&@CRLF)
    EndFunc

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

    Func shiftRight($array)
    Local $narray,$len

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

    $narray = $array
    $len = UBound($array)

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

    For $i=0 To $len-1 Step 1
    Local $newPlace = $i+1

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

    If $newPlace > $len-1 Then
    $newPlace = 0
    EndIf

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

    $narray[$newplace] = $array[$i]
    Next

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

    Return $narray
    EndFunc

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

    Func shiftLeft($array)
    Local $narray,$len

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

    $narray = $array
    $len = UBound($array)

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

    For $i=0 To $len-1 Step 1
    Local $newPlace = $i-1

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

    If $newPlace < 0 Then
    $newPlace = $len-1
    EndIf

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

    $narray[$newplace] = $array[$i]
    Next

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

    Return $narray
    EndFunc

    [/autoit]

    Einmal editiert, zuletzt von bluelamp (1. April 2010 um 13:52)

  • Wollte meine Lösung auch noch posten. Meine ist noch ein wenig übersichtlicher und kürzer :P
    Funktion _ArrayShift (benötigt #include <Array.au3>)

    Spoiler anzeigen
    [autoit]

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _ArrayShift
    ; Description ...: Verschiebt den Inhalt eines Array um die angegebene Zahl nach links oder rechts
    ; Syntax.........: _ArrayShift(ByRef $aShift, $iShift)
    ; Parameters ....: $aShift - Zu bearbeitendes Array
    ; $iShift - Integerzahl um die verschoben werden soll (Bei $iShift < 0 wird nach links verschoben)
    ; Return values .: Erfolg - 1
    ; Fehler - 0, setzt @error:
    ; |-1 - $aShift ist kein Array
    ; |-2 - $iShift ist keine Integerzahl
    ; Author ........: name22
    ; Includes.......: Array.au3
    ; ===============================================================================================================================
    Func _ArrayShift(ByRef $aShift, $iShift)
    If Not IsInt($iShift) Then Return SetError(-2, 0, 0)
    If Not IsArray($aShift) Then Return SetError(-1, 0, 0)
    $iSize = UBound($aShift)
    $iShift *= -1
    If $iShift < 0 Then
    $iShift *= -1
    $iShift = $iSize - $iShift
    EndIf
    For $iI = 1 To $iShift
    For $i = 0 To $iSize - 1
    $iNew = $i + 1
    If $iNew > $iSize - 1 Then $iNew -= 1
    _ArraySwap($aShift[$i], $aShift[$iNew])
    Next
    Next
    Return 1
    EndFunc ;==>_ArrayShift

    [/autoit]


    Anwendungsbeispiel:

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>

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

    Dim $aTest[20]

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

    For $i = 0 To UBound($aTest) - 1
    $aTest[$i] = $i
    Next

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

    _ArrayDisplay($aTest)
    _ArrayShift($aTest, 4)
    _ArrayDisplay($aTest)
    _ArrayShift($aTest, -8)
    _ArrayDisplay($aTest)

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

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _ArrayShift
    ; Description ...: Verschiebt den Inhalt eines Array um die angegebene Zahl nach links oder rechts
    ; Syntax.........: _ArrayShift(ByRef $aShift, $iShift)
    ; Parameters ....: $aShift - Zu bearbeitendes Array
    ; $iShift - Integerzahl um die verschoben werden soll (Bei $iShift < 0 wird nach links verschoben)
    ; Return values .: Erfolg - 1
    ; Fehler - 0, setzt @error:
    ; |-1 - $aShift ist kein Array
    ; |-2 - $iShift ist keine Integerzahl
    ; Author ........: name22
    ; Includes.......: Array.au3
    ; ===============================================================================================================================
    Func _ArrayShift(ByRef $aShift, $iShift)
    If Not IsInt($iShift) Then Return SetError(-2, 0, 0)
    If Not IsArray($aShift) Then Return SetError(-1, 0, 0)
    $iSize = UBound($aShift)
    $iShift *= -1
    If $iShift < 0 Then
    $iShift *= -1
    $iShift = $iSize - $iShift
    EndIf
    For $iI = 1 To $iShift
    For $i = 0 To $iSize - 1
    $iNew = $i + 1
    If $iNew > $iSize - 1 Then $iNew -= 1
    _ArraySwap($aShift[$i], $aShift[$iNew])
    Next
    Next
    Return 1
    EndFunc ;==>_ArrayShift

    [/autoit]
    • Offizieller Beitrag

    Ich finde, viel besser als ein tatsächliches Shift ist ein virtuelles Shift (vor allem bei großen Arrays). Da braucht man das Array nicht umbauen. Dazu muß man dann zwar den Index in einem extra Indexarray führen, aber die Indexe umschreiben sollte doch wesentlich performanter sein als das Array kpl. umzubauen.

  • BugFix meinst du so?

    Spoiler anzeigen
    [autoit]


    Dim $aTest[20]

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

    For $i = 0 To UBound($aTest) - 1
    $aTest[$i] = $i
    Next

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

    _ArrayDisplay($aTest)
    _ArrayShift($aTest, 21)
    _ArrayDisplay($aTest)

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

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _ArrayShift
    ; Description ...: Verschiebt den Inhalt eines Array um die angegebene Zahl nach links oder rechts
    ; Syntax.........: _ArrayShift(ByRef $aShift, $iShift)
    ; Parameters ....: $aShift - Zu bearbeitendes Array
    ; $iShift - Integerzahl um die verschoben werden soll (Bei $iShift < 0 wird nach links verschoben)
    ; Return values .: Erfolg - 1
    ; Fehler - 0, setzt @error:
    ; |-1 - $aShift ist kein Array
    ; |-2 - $iShift ist keine Integerzahl
    ; Author ........: name22, clezZ
    ; ===============================================================================================================================
    Func _ArrayShift(ByRef $aShift, $iShift)
    If Not IsInt($iShift) Then Return SetError(-2, 0, 0)
    If Not IsArray($aShift) Then Return SetError(-1, 0, 0)

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

    $iShift *= -1
    Local $iSize = UBound($aShift)

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

    If $iShift < 0 Then
    $iShift *= -1
    $iShift = $iSize - $iShift
    EndIf
    If $iShift > $iSize Then
    While $iShift > $iSize
    $iShift -= $iSize
    WEnd
    EndIf

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

    Local $aBuffer[$iSize]
    For $i = 0 To $iSize - 1
    $iNew = $i + $iShift
    If $iNew > $iSize - 1 Then $iNew -= $iSize
    $aBuffer[$i] = $aShift[$iNew]
    Next

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

    $aShift = $aBuffer
    Return 1
    EndFunc ;==>_ArrayShift

    [/autoit]


    Das ist jetzt logischerweise um einiges schneller :)