TIA Variant Bubblesort

Ingo dV

Level-1
Beiträge
61
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Moin,
ich habe mir die Aufgabe gestellt in TIA V13 ein flexibles Bubblesort zu erstellen, was mit der symbolischen Zuordnung eines Arrays als Parameterübergabe funktioniert.
Wo ich eine Lösung gefunden habe:
Durch das Nutzen eines Variant habe ich eine flexible Arraylänge als IN/OUT, dies funktioniert allerdings nur bis zu einer, im Baustein vorgegebenen maximal Länge (hier 64)
Durch das Prüfen des Variabletyps im Array kann ich jetzt 2 Typen (DINT und INT) verwenden, weitere Typen sind natürlich programmierbar.

Wo ich keine Lösung gefunden habe:
Flexible Arraylänge ohne maximal Länge im Baustein
Flexible Arraytypen ohne die Bearbeitungsschleifen quasi immer wieder gleich, nur mit einer anderen Variablentype im Array zu programmieren.

Ich schmeiße euch den Code mal als 'Bastelvorlage' vor die Füße, vielleicht hat ja der ein oder andere eine gute Idee und Postet die hier.

Code:
Deklaration:

Input            
    MaxToMin    Bool        Von Maximalwert zu Minimalwert sortieren
    Compress    Bool        Nullwerte Ausfiltern
                
InOut            
    Daten    Variant        Maximal 64 Werte

    Temp            
    Array_DINT    Array[1..#ArraySize] of DInt    Array
    Array_INT     Array[1..#ArraySize] of Int     Array
    Sort_DINT     DInt                                    Sortierwert DINT
    Sort_INT      Int                                     Sortierwert INT
    Size          UDInt                                   Anzahl Daten (Array Größe)
    Loop          SInt                                    Anzahl Schleifen
    CNT1          SInt                                    Schleife 1
    CNT2          SInt                                    Schleife 2
    Result        Int                                     Fehlerinformation
    
Constant            
    ArraySize            Int    64    Maximale Arraygrösse für Bubblesort

// ________________________________________________________________________________________________________________________________________
// Bubblesort
// ________________________________________________________________________________________________________________________________________


(* Der Baustein sortiert ein Array of INT oder DINT (bis 64 Eintrage, erweiterbar durch die Konstante ArraySize) von Min nach Max oder umgekehrt.
Durch die Vorgabe 'Compress' werden  Einträge mit Wert '0' ausgefiltert. *)


// +++ Variant auf Array prüfen +++
IF NOT IS_ARRAY(#Daten) THEN
    RETURN;
END_IF;


// +++ Anzahl Arrayelemente/Schleifenlänge ermitteln +++
#Size := CountOfElements(#Daten);
#Loop := UDINT_TO_SINT(#Size);


// ________________________________________________________________________________________________________________________________________
// DINT sortieren
// ________________________________________________________________________________________________________________________________________


// +++ Prüfe ob Array im DINT Format ist +++
IF TypeOfElements(#Daten) = TypeOf(#Array_DINT[1]) THEN
    
    #Result := MOVE_BLK_VARIANT(SRC := #Daten, COUNT := #Size, SRC_INDEX := 0, DEST_INDEX := 0, DEST => #Array_DINT);
    
    // +++ Bei Vorwahl Compress Null-Werte nach unten sortieren +++
    IF #Compress THEN
        FOR #CNT1 := 1 TO #Loop - 1 DO
            FOR #CNT2 := #CNT1 + 1 TO #Loop DO
                IF (#Array_DINT[#CNT1] = 0) THEN
                    #Array_DINT[#CNT1] := #Array_DINT[#CNT2];
                    #Array_DINT[#CNT2] := 0;
                END_IF;
            END_FOR;
        END_FOR;
    END_IF;
    
    // +++ Array von klein nach groß oder von groß nach klein sortieren +++
    FOR #CNT1 := 1 TO #Loop - 1 DO
        FOR #CNT2 := #CNT1 + 1 TO #Loop DO
            IF ((#Array_DINT[#CNT1] > #Array_DINT[#CNT2] AND (#Array_DINT[#CNT2] <> 0 OR NOT #Compress) AND NOT #MaxToMin))
                OR ((#Array_DINT[#CNT1] < #Array_DINT[#CNT2] AND (#Array_DINT[#CNT2] <> 0 OR NOT #Compress) AND #MaxToMin)) THEN
                #Sort_DINT := #Array_DINT[#CNT1];
                #Array_DINT[#CNT1] := #Array_DINT[#CNT2];
                #Array_DINT[#CNT2] := #Sort_DINT;
            END_IF;
        END_FOR;
    END_FOR;
    
    #Result := MOVE_BLK_VARIANT(SRC := #Array_DINT, COUNT := #Size, SRC_INDEX := 0, DEST_INDEX := 0, DEST => #Daten);
    RETURN;
    
 // ________________________________________________________________________________________________________________________________________
 // INT sortieren
 // ________________________________________________________________________________________________________________________________________
 
    // +++ Prüfe ob Array im INT Format ist +++
ELSIF TypeOfElements(#Daten) = TypeOf(#Array_INT[1]) THEN
    
    #Result := MOVE_BLK_VARIANT(SRC := #Daten, COUNT := #Size, SRC_INDEX := 0, DEST_INDEX := 0, DEST => #Array_INT);
    
    // +++ Bei Vorwahl Compress Null-Werte nach unten sortieren +++
    IF #Compress THEN
        FOR #CNT1 := 1 TO #Loop - 1 DO
            FOR #CNT2 := #CNT1 + 1 TO #Loop DO
                IF (#Array_INT[#CNT1] = 0) THEN
                    #Array_INT[#CNT1] := #Array_INT[#CNT2];
                    #Array_INT[#CNT2] := 0;
                END_IF;
            END_FOR;
        END_FOR;
    END_IF;
    
    // +++ Array von klein nach groß oder von groß nach klein sortieren +++
    FOR #CNT1 := 1 TO #Loop - 1 DO
        FOR #CNT2 := #CNT1 + 1 TO #Loop DO
            IF ((#Array_INT[#CNT1] > #Array_INT[#CNT2] AND (#Array_INT[#CNT2] <> 0 OR NOT #Compress) AND NOT #MaxToMin))
                OR ((#Array_INT[#CNT1] < #Array_INT[#CNT2] AND (#Array_INT[#CNT2] <> 0 OR NOT #Compress) AND #MaxToMin)) THEN
                #Sort_INT := #Array_INT[#CNT1];
                #Array_INT[#CNT1] := #Array_INT[#CNT2];
                #Array_INT[#CNT2] := #Sort_INT;
            END_IF;
        END_FOR;
    END_FOR;
    
    #Result := MOVE_BLK_VARIANT(SRC := #Array_INT, COUNT := #Size, SRC_INDEX := 0, DEST_INDEX := 0, DEST => #Daten);
END_IF;


// ________________________________________________________________________________________________________________________________________
// Baustein Ende
// ________________________________________________________________________________________________________________________________________
 
Hallo,
mal so eine Frage am Rande )ich habe mich nicht näher mit deinem Code auseinander gesetzt) :
Warum nimmst du nicht ANY für die Daten-Versorgung ? Damit könntest du auf alle Fälle viel größere Bereiche übergeben ...

Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Larry, meine Intension ist die Möglichkeiten von TIA auszuschöpfen, Variant statt ANY ist da ja jetzt 'state of the art'.
Weiterhin ist ANY, da absolut adressiert, nicht in optimierten Bausteinen möglich. Ich möchte eigentlich vollsymbolische generische Bausteine erzeugen, die wenn benötigt z.B. Array nutzen, die sowohl in der Datenbreite als auch im Type variabel sind (z.B. Array[#Begin .. #End of #Type]). Mit V13 sind ja einige Neuerungen gekommen wie z.B. die Möglichkeiten Arrays per Konstante 'variabel' zu machen und mit Variant (ist ja noch nicht so etabliert, da recht neu) kann man schon jetzt einige schöne Dinge tun aber halt noch nicht alles - was meinen Wissenstand betrifft jedenfalls - und darum die Frage ins Forum. So ganz up to Date was den Befehlsvorrat angeht bin ich noch nicht, die Doku ist auch noch verbesserungswürdig - oder ich denk zu quer, das kommt auch schon mal vor :D
 
warum eigentlich bubblesort?

naja, soll wohl so sein - wie dem auch sei, der normale Ansatz wäre, das Temp Array zur Laufzeit zu deklarieren - das Problem ist, dass TIA das sehr wahrscheinlich nicht unterstützt.
vom Gefühl her? maximale Länge festlegen und aus.
 
Ändert aber auch nichts an der Tatsache, dass TIA (bzw. die verwendete SPS) das Array nicht zur Laufzeit deklarieren kann und der TE sich damit vorher für eine maximale Größe entscheiden muss.
 
Zuletzt bearbeitet:
Für die eierlegende Wollmilchsau?
Einmal erstellen, nur kopieren und nicht mal mehr die Konstanten anpassen.

Die benötigte Größe des Temparrays also zur Laufzeit auf die Größe der verschiedenen zu sortierenden Arrays anpassen, um auch möglichst nicht unnötig viel zu sortieren, wo gar nichts mehr ist.
 
Für die eierlegende Wollmilchsau?
Einmal erstellen, nur kopieren und nicht mal mehr die Konstanten anpassen.

Die benötigte Größe des Temparrays also zur Laufzeit auf die Größe der verschiedenen zu sortierenden Arrays anpassen, um auch möglichst nicht unnötig viel zu sortieren, wo gar nichts mehr ist.

nein, ein grundsätzlicheres wozu ... wozu muss ich ganze arrays sortieren?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Die Idee dahinter sind generische Bausteine, die optimiert Speicher benötigen und in Bibliotheken eingebunden sind und nicht verändert werden sollen. Zur Laufzeit veränderbare Array sind für solche Ziele unabdingbar und somit - zu mindest von meiner Seite aus gesehen - wünschenswert.

PS: Bubblesort statt Quicksort da es nicht um das Verfahren sondern den Lösungsweg geht und Bubble halt sehr einfach ist.
 
Zurück
Oben