Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Sortiern nach Datum (strings) (https://www.delphipraxis.net/152147-sortiern-nach-datum-strings.html)

eragon123 13. Jun 2010 00:37

Sortiern nach Datum (strings)
 
Ich habe eine Liste von Daten, die allerdings in Form von Strings gespeichert sind. Die sehen so aus:
Code:
z.B. : 20.02.09 - 05.04.09
Code:
06.04.09 - 07.06.09
Wie kann ich diese jetzt sortieren? Ich hab es mal mit einem einfachen Bubblesort getestet, aber das schien nicht zu funktionieren.

Luckie 13. Jun 2010 01:57

AW: Sortiern nach Datum (strings)
 
Konvertiere die Zeichenfolgen erst in ein Datumsformat und sortiere dann dieses.

idefix2 13. Jun 2010 09:09

AW: Sortiern nach Datum (strings)
 
Zitat:

Ich hab es mal mit einem einfachen Bubblesort getestet, aber das schien nicht zu funktionieren.
Warum sollte ein einfacher Bubblesort gerade da nicht funktionieren?

Der Schlüssel zum Sortieren ist die Vergleichsroutine, mit einem direkten Stringvergleich wirst Du nicht weit kommen, weil der ja alphabetisch und nicht nach Datum sortiert. Aber wenn die Vergleichsfunktion die Daten richtig vergleicht, wird jeder (richtig implementierte) Sortieralgorithmus sortieren.

Wenn Du Dir das vorherige Konvertieren in ein Datumsformat sparen willst:

function less (a,b: string): boolean;
begin
less := copy(a,7,2)+copy(a,4,2)+copy(a,1,2) < copy(b,7,2)+copy(b,4,2)+copy(b,1,2)
end;

Wenn es sich nur um relativ wenige Werte handelt, ist die Ineffizienz, die durch den Zusatzaufwand bei jedem einzelnen Vergleich entsteht, gleichgültig. Die Funktion funktioniert natürlich nur für Daten ab dem Jahr 2000 mit jeweils zweistellig angegebener Jahreszahl, Monatszahl und Tageszahl.

xZise 13. Jun 2010 10:30

AW: Sortiern nach Datum (strings)
 
Moin,

Interessant wäre auch, wie du sortiert hast. Weil BubbleSort sagt ja nur wie man etwas sortiert, aber nicht genau wie man den Code schreibt. Und nach was willst du sortieren? Erstes Datum? Zweites Datum? Differenz?

Und dann ist die Vergleichsoperation wichtig. In der Regel (um sowas dynamisch zu gestalten) wird eine Methode genommen die beide Werte bekommt und -1, 0 oder +1 zurückgibt (so ähnlich wie Delphi-Referenz durchsuchenCompareString) und damit sagt, welcher von beiden ist größer.

Ich würde also einfach den Pseudocode aus der Wikipedia nehmen und nach Delphi übersetzen:
Delphi-Quellcode:
function bubbleSort( A : array of <Datentyp> ) : array of <Datentyp>;
begin
  n := Length(A);
  repeat
    swaped := false;
    for i := 0 to n - 2 do
    begin
      if Compare(A[ i ], A[ i + 1 ]) > 0 then
      begin
        // A[i] und A[i + 1] vertauschen
        swaped := true;
      end
    end
    n := n - 1
  until (n < 1) or (not swaped);
end;
Du musst jetzt nur noch die Elemente A[i] und A[i + 1] vertauschen. Ich bin mir nicht sicher ob ein Array als Referenz übergeben wird, also man kein Rückgabewert braucht. Außerdem musst du noch eine Compare-Funktion schreiben (s.o.) die halt einen Wert größer 0 (i.d.R. wird +1 genommen) zurückgibt, wenn das erste Element größer ist als das zweite.

MfG
Fabian

idefix2 13. Jun 2010 16:16

AW: Sortiern nach Datum (strings)
 
Delphi-Quellcode:
until (n >= 1) and (swaped);
das kanns aber nicht sein. Sollte sein

Delphi-Quellcode:
until (n<1) or not swaped;
Und aufpassen, ein dynamisches array beginnt bei Index 0

xZise 13. Jun 2010 16:41

AW: Sortiern nach Datum (strings)
 
Ah mist :D In Java gibt es
Code:
while() {}
und
Code:
do {} while()
und beide berechen ab, wenn die Bedingungen nicht zutreffen. Bei Delphi war das ja anders :oops:

Habe den Code mal korrigiert.

MfG
Fabian

PS: Der Off-by-One-Error ist ja beschäment :pale:
PPS: Warum ist das jetzt nicht inline.... hmpf

idefix2 13. Jun 2010 17:00

AW: Sortiern nach Datum (strings)
 
Noch immer nicht ganz. Es würde zwar so funktionieren, aber mit unnötigen Schleifendurchläufen.
Statt "and" gehört "or" in die Abbruchbedingung, wenn in einem Durchlauf keine Elemente vertauscht werden, ist das feld fertig sortiert.

Amateurprofi 14. Jun 2010 01:14

AW: Sortiern nach Datum (strings)
 
Noch besser wäre es m.E. so
1) Am Anfang n nicht auf die Länge des Arrays stellen, sondern auf den höchsten Index.
2) Das Senken von n um 1 nicht am Ende der Repeat-Schleife ausführen, sondern am Anfang.
3) Die For-Schleife von 0 bis n laufen lassen.
4) Beim Until nur swaped abfragen. Die Abfrage, ob n einen bestimmten Grenzwert erreicht hat, ist bei dieser Konstruktion überflüssig.

Delphi-Quellcode:
function bubbleSort( A : array of <Datentyp> ) : array of <Datentyp>;
begin
  n := High(A);
  repeat
    n := n - 1;
    swaped := false;
    for i := 0 to n do
      if Compare(A[ i ], A[ i + 1 ]) > 0 then
      begin
        // A[i] und A[i + 1] vertauschen
        swaped := true;
      end
  until not swaped;
end;

xZise 14. Jun 2010 09:17

AW: Sortiern nach Datum (strings)
 
Es geht hier ja eigentlich nicht um den besten Sortieralgorithmus (da kann man Mergesort, Quicksort oder Heapsort nehmen), sondern darum, dass er überhaupt erstmal sortiert.

Leider meldet sich der Threadersteller nicht mehr.

MfG
Fabian

eragon123 14. Jun 2010 23:01

AW: Sortiern nach Datum (strings)
 
Danke für die Hilfe.
Ich habe jetzt erst einmal dieser Variante
Delphi-Quellcode:
function less (a,b: string): boolean;
begin
less := copy(a,7,2)+copy(a,4,2)+copy(a,1,2) < copy(b,7,2)+copy(b,4,2)+copy(b,1,2)
end;
genutzt. So schnell muss es nicht sein da nur maximal ca. 100 Datensätze sortiert werden müssen.

Luckie 14. Jun 2010 23:32

AW: Sortiern nach Datum (strings)
 
So bald sich aber das Datumsformat ändert, funktioniert der Code nicht mehr!

mkinzler 15. Jun 2010 06:28

AW: Sortiern nach Datum (strings)
 
Deshalb ist es ja auch keine gute Idee Datumswerte als Strings abzulegen

idefix2 15. Jun 2010 08:40

AW: Sortiern nach Datum (strings)
 
@Luckie, mkinzler

im Prinzip habt ihr Recht, aber es hängt natürlich von den Anforderungen an das Programm ab.

Wenn die Daten jetzt schon in diesem Format vorliegen und dabei in absehbarer Zeit keine Änderung vorgesehen ist, kann man das wohl so lassen und seine Energie genausogut in andere Sachen stecken :)

himitsu 15. Jun 2010 08:47

AW: Sortiern nach Datum (strings)
 
Wenn die Datumsstrings programmintern erzeugt werden, dann sollte man sich dazu auch eine passende Umkehrfunktion auswählen.
DateToStr <> StrToDate sollte im laufenden Betrieb kaum probleme bereiten, es sei denn jemand spielt an den Systemoptionen rum oder man verbietet seinem Delphiprogramm nicht, die neuen Daten zu importierern.

Sollten diese Strings aber auch noch gespeichert oder übertragen werden und es muß unbedingt ein String sein, dann sollte man ein bestimmtes Datumsformat festlegen, welches sich dann auch leicht dekodieren läßt.

PS: Es gibt auch Datumsformate, welche sich direkt als String vergleichen lassen ... also alles welches dieses als irgendwelche Folgen von YY-MM-DD, btw. YYYY-MM-DD enthält. :stupid:

xZise 15. Jun 2010 10:33

AW: Sortiern nach Datum (strings)
 
Zitat:

Zitat von eragon123 (Beitrag 1028886)
Danke für die Hilfe.
Ich habe jetzt erst einmal dieser Variante
Delphi-Quellcode:
function less (a,b: string): boolean;
begin
less := copy(a,7,2)+copy(a,4,2)+copy(a,1,2) < copy(b,7,2)+copy(b,4,2)+copy(b,1,2)
end;
genutzt. So schnell muss es nicht sein da nur maximal ca. 100 Datensätze sortiert werden müssen.

Aber das ist doch keine Sortierung? Oder ging es dir eher darum, wie vergleiche ich zwei Strings miteinander?

MfG
Fabian

idefix2 15. Jun 2010 13:21

AW: Sortiern nach Datum (strings)
 
Er ist bei seinem Sortierprogramm darüber gestolpert, dass er Datumswerte, die als Strings vorliegen, falsch vergleicht - und deshalb falsch sortiert.

eragon123 15. Jun 2010 15:35

AW: Sortiern nach Datum (strings)
 
Genauso ist es.
Die Daten sind in Form von Strings, da meine Quelle das genauso her gibt. Und das erst umzuwandeln lohnt sich vom Aufwand her nicht.


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:10 Uhr.

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