Delphi-PRAXiS
Seite 2 von 4     12 34   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Sortieren eines Arrays of String (https://www.delphipraxis.net/201283-sortieren-eines-arrays-string.html)

DonPedroFo 8. Jul 2019 13:40

AW: Sortieren eines Arrays of String
 
Vielen Dank für die zahlreichen Antworten. Das hilf mir enorm weiter.
@Delphi.Narium
deine Lösung finde ich am plausibelsten. Da kann ich auch nachvollziehen was im Hintergrund abläuft.

Vielen Dank manchmal scheint mir es am Ende einfacher als es am Anfang aussieht.

Mavarik 8. Jul 2019 16:13

AW: Sortieren eines Arrays of String
 
Zitat:

Zitat von DonPedroFo (Beitrag 1436290)
@Delphi.Narium
deine Lösung finde ich am plausibelsten. Da kann ich auch nachvollziehen was im Hintergrund abläuft.

Wenn es Dir nicht auf die Geschwindigkeit ankommt, kannst Du den BubbleSort von Delphi.Narium nehmen, schneller ist natürlich der Ansatz vom schönen Günter... ggf. einfach mit einem String vergleich und nicht per RegEx!

Mavarik

Andreas13 8. Jul 2019 16:53

AW: Sortieren eines Arrays of String
 
Hallo,
wenn es jetzt schon um die Sortiergeschwindigkeit geht (wir reden hierbei nicht unbedingt nur über die zu sortierenden 98 Datensätzen), dann möchte ich auch meinen „Senf“ dazu geben und einen vollkommen anderen Ansatz zeigen. Zunächst möchte jedoch auch ich feststellen, daß
a):
die Lösung von Der schöne Günther sehr professionell & komplex ist und viel Know-how enthält und voraussetzt.
b):
die Lösung von Delphi.Narium sehr kompakt, verständlich und elegant ist und sortiert direkt im Memo.

Mein Ansatz sieht wie folgt aus: Da DonPedroFo die „Adressen“ bereits aus seinen Stringzeilen extrahiert hat, könnte er (wenn er Zeit & Lust zum Experimentieren hat) folgendes machen:
1):
Die extrahierten „Adressen“ in einen IntegerVektor (= Array of Integer) packen,
2):
Die kompletten Original-Strings (unverändert) in einen StringVektor (= Array of String) laden.

Ich habe vor längerer Zeit eine Routine zum MIT-Sortieren von gekoppelten Extended- und Integer-Vektoren (= Arrays) entwickelt, dessen Code unten folgt. Der MasterVektor wird hierbei sortiert, der Rest (in der Routine 3 weitere Vektoren) erfährt aber dieselben Tauschaktionen, wird also quasi mitsortiert.
In DonPedroFo's Fall wäre der zu sortietrende IntegerVektor der MasterVektor. Der StringVektor wird ohne Vergleichsoperationen nur "mitbewegt". Mit geringem Aufwand lässt sich meine Routine anpassen. Gegebenenfalls kann man die überflüssigen Vektoren löschen oder einfach den NILVektor-DummyParameter übergeben.
Delphi-Quellcode:
Type
  TDynExtendedVektor = TArray<Extended>; // = Array of Extended;
  TDynIntegerVektor = TArray<Integer>; // Array of Integer;


(* Krücken: sie sollten eigentlich CONSTANT sein: es geht aber NICHT! *)
VAR
  NILVektor_Extended: TDynExtendedVektor;
  NILVektor_Integer : TDynIntegerVektor;
 (* Eigentlich Krücken: sie sollten eigentlich CONSTANT sein: es geht aber NICHT!
  Solange Länge NICHT gesetzt wird, ist es ein NIL-Vektor bzw. eine NIL-Matrix *)



Procedure MIT_Sort_Extended_Vektor_byQuick(VAR A_Vektor_MASTER: TDynExtendedVektor;
                                                  VAR B_Vektor: TDynExtendedVektor;
                                                  VAR C_Vektor: TDynExtendedVektor;
                                                  VAR I_Vektor: TDynIntegerVektor;
                                                   Aufsteigend: Boolean = True);

// Angepasst nach Easy Delphi Helper's QuickSort für Integer_Vektor; Rekursiv --> STACK!!
// Zum MIT_Sortieren zugehöriger Vektoren
// QuickSort ist ein rekursives (STACK!!!), instabliles (!!) Sortierverfahren,
// Problematisch ist, wenn zwei Einträge genau gleich sind
//
// beim Fehlen eines Vektors, als Parameter folgende Dummys übergeben:
// NILVektor_Extended: TDynExtendedVektor;
// NILVektor_Integer : TDynIntegerVektor;

  Procedure Quick_Sort(Var a: TDynExtendedVektor; VAR b: TDynExtendedVektor;
                       VAR c: TDynExtendedVektor; VAR iV: TDynIntegerVektor; iLo, iHi: Integer);

  var
    Lo, Hi : Integer;
    Mid, T : Extended;
    T_B, T_C: Extended;
    T_i    : Integer;

  Begin
    Lo := iLo;
    Hi := iHi;
    Mid:= a[(Lo + Hi) div 2];
    Repeat
      While a[Lo] < Mid Do
        Inc(Lo);

      While a[Hi] > Mid Do
        dec(Hi);

      IF Lo <= Hi Then Begin // ALLE Vertauschungen sind HIER:
        // A:
        T   := a[Lo];
        a[Lo]:= a[Hi];
        a[Hi]:= T;

        // B:
        IF b <> NIL Then Begin
          // NIL lässt sich NICHT DIREKT als Paramter für den Vektor übergeben, nur über einen Dummy-Vektor: NILVektor_Extended oder NILVektor_Integer
          T_B := b[Lo];
          b[Lo]:= b[Hi];
          b[Hi]:= T_B;
        End;

        // C:
        IF c <> NIL Then Begin
          // NIL lässt sich NICHT DIREKT als Paramter für den Vektor übergeben, nur über einen Dummy-Vektor: NILVektor_Extended oder NILVektor_Integer
          T_C := c[Lo];
          c[Lo]:= c[Hi];
          c[Hi]:= T_C;
        End;

        // iV:
        IF iV <> NIL Then Begin
          // NIL lässt sich NICHT DIREKT als Paramter für den Vektor übergeben, nur über einen Dummy-Vektor: NILVektor_Extended oder NILVektor_Integer
          T_i  := iV[Lo];
          iV[Lo]:= iV[Hi];
          iV[Hi]:= T_i;
        End;

        Inc(Lo);
        dec(Hi);
      End;
    Until Lo > Hi;

    IF Hi > iLo Then
      Quick_Sort(A_Vektor_MASTER, B_Vektor, C_Vektor, I_Vektor, iLo, Hi);

    IF Lo < iHi Then
      Quick_Sort(A_Vektor_MASTER, B_Vektor, C_Vektor, I_Vektor, Lo, iHi);
  End;

Begin
  // Rekursiver Aufruf:
  Quick_Sort(A_Vektor_MASTER, B_Vektor, C_Vektor, I_Vektor, Low(A_Vektor_MASTER), High(A_Vektor_MASTER));

  IF Aufsteigend Then
    Exit;

  // Absteigend: -> Krücke: Umkopieren!
  Vektor_Umsortieren(A_Vektor_MASTER, B_Vektor, C_Vektor, I_Vektor);
End;{MIT_Sort_Extended_Vektor_byQuick}
{------------------------------------}

Procedure Vektor_Umsortieren(VAR A_Vektor: TDynExtendedVektor;
                             VAR B_Vektor: TDynExtendedVektor;
                             VAR C_Vektor: TDynExtendedVektor;
                             VAR I_Vektor: TDynIntegerVektor); overload;

// Dreht die Sortierfolge durch Umkopieren um: Aufsteigend --> Absteigend bzw. Absteigend --> Aufsteigend
// ist nur eine Krücke, Doch der Aufwand, direkt Absteigend zu sortieren ist viel größer...
// beim Fehlen eines Vektors, als Parameter folgrnde Dummys übergeben:
// NILVektor_Extended: TDynExtendedVektor;
// NILVektor_Integer : TDynIntegerVektor;

VAR
  i, j, tmp_i       : Integer;
  tmp_A, tmp_B, tmp_C: Extended;

Begin
  j:= High(A_Vektor);

Begin
  For i:= Low(A_Vektor) To (High(A_Vektor) div 2) Do Begin
    // A:
    tmp_A     := A_Vektor[i];
    A_Vektor[i]:= A_Vektor[j];
    A_Vektor[j]:= tmp_A;

    // B:
    IF B_Vektor <> NIL Then Begin
      // NIL lässt sich NICHT DIREKT als Paramter für den Vektor übergeben, nur über einen Dummy-Vektor: NILVektor_Extended oder NILVektor_Integer
      tmp_B     := B_Vektor[i];
      B_Vektor[i]:= B_Vektor[j];
      B_Vektor[j]:= tmp_B;
    End;

    // C:
    IF C_Vektor <> NIL Then Begin
      // NIL lässt sich NICHT DIREKT als Paramter für den Vektor übergeben, nur über einen Dummy-Vektor: NILVektor_Extended oder NILVektor_Integer
      tmp_C     := C_Vektor[i];
      C_Vektor[i]:= C_Vektor[j];
      C_Vektor[j]:= tmp_C;
    End;

    // Integer:
    IF I_Vektor <> NIL Then Begin
      // NIL lässt sich NICHT DIREKT als Paramter für den Vektor übergeben, nur über einen Dummy-Vektor: NILVektor_Extended oder NILVektor_Integer
      tmp_i     := I_Vektor[i];
      I_Vektor[i]:= I_Vektor[j];
      I_Vektor[j]:= tmp_i;
    End;

    dec(j);
  End;
End;{Vektor_Umsortieren}
{----------------------}
Vielleicht hilft es jemandem in ähnlichen Aufgabenstellungen weiter.
Gruß
Andreas

DeddyH 8. Jul 2019 17:51

AW: Sortieren eines Arrays of String
 
Falls die Angabe "Delphi 5" tatsächlich stimmt, lösen sich alle generischen Lösungen in Rauch auf, daher hatte ich mir das vorsichtshalber verkniffen.

samso 8. Jul 2019 20:50

AW: Sortieren eines Arrays of String
 
Warum soll das erst sortiert werden? Da ja am Ende die Daten sowieso in das Flash geschrieben werden sollen, kannst Du auch direkt eine Kopie der Flashdaten im RAM anlegen. Du reservierst die 64 Kilobyte und kopierst dann die Daten direkt nachdem du zwei Hexziffern zu einem Byte konvertiert hast an die richtige Stelle in das 64 Kilobyte-Array. Die Adresse wo das hin muss hast Du ja. Danach kannst Du das komplette Byte-Array, so wie es ist in den Flash-Speicher kopieren.

p80286 8. Jul 2019 22:04

AW: Sortieren eines Arrays of String
 
Keine schlechte Idee, dann wäre es allerdings auch sinnvoll die Daten gleich auf Konsiztenz zu prüfen. Es könnte doch peinlich sein, wenn es Löcher oder Überschneidungen gäbe.

Gruß
K-H

DonPedroFo 10. Jul 2019 09:50

AW: Sortieren eines Arrays of String
 
Die Angabe Delphi 5 stimmt :D

Ich komme mit der kurzen Variante von Delphi.Narium gut zurecht.
Im großen und ganzen hätte ich da bestimmt auch selber drauf kommen können.
Aber trotzdem vielen Dank. Die nächste Frage lauert schon in meinem Kopf. Lang dauert es nicht mehr bis ich sie stelle.

DonPedroFo 10. Jul 2019 13:07

AW: Sortieren eines Arrays of String
 
Ich weiß nicht ob ich die Frage hier anhängen kann oder ob ich einen neuen Thread auf machen sollte.

Es geht um folgendes:

Da ich unterschiedlich lange Datenfelder habe, hab ich die einzelnen Längen von jedem String bzw. die Länge vom Längsten String ermittelt und "gespeichert".

Zum späteren programmieren müssen alle Strings im Datenfeld eine Bestimmte Länge haben z.b.

Vorher:
S01122334455666
S0112233
S01144
S011

Nachher:
S0112233445566
S0112233FFFFFF
S01144FFFFFFFF
S011FFFFFFFFFF

Was ich damit sagen will ist, das ich die Länge vom längsten String als Referenzlänge nehme und alle Strings die kleiner sind mit "F" auffülle bis sie die gewünschte länge haben.

Ich hab das ganze schon mit FillChar(Datenfeld,Sizeof(XX),X);

Wie kann ich hier eine Länge bzw. "F" angeben?

Andreas13 10. Jul 2019 13:52

AW: Sortieren eines Arrays of String
 
Verscuh es mal mit der Funktion System.WideString.StringOfChar(WideChar ch, int count):
Delphi-Quellcode:
// ungetestet:
String_Lang:= String_kurz + StringOfChar('F', Len_Soll - Length(String_kurz));
Gruß
Andreas

DeddyH 10. Jul 2019 14:39

AW: Sortieren eines Arrays of String
 
In Delphi 5 war die IIRC in SysUtils, wenn es sie überhaupt schon gab.


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:28 Uhr.
Seite 2 von 4     12 34   

Powered by vBulletin® Copyright ©2000 - 2022, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf