AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign Delphi Funktion kommt beim sortieren des Array durcheinander
Thema durchsuchen
Ansicht
Themen-Optionen

Funktion kommt beim sortieren des Array durcheinander

Ein Thema von Popov · begonnen am 16. Feb 2012 · letzter Beitrag vom 17. Feb 2012
Antwort Antwort
Popov
(Gast)

n/a Beiträge
 
#1

Funktion kommt beim sortieren des Array durcheinander

  Alt 16. Feb 2012, 18:20
Ich verwalte paar Infos über ein Record-Array. Das einzig besondere dabei ist die Bitmap. Da ich vorher nicht weiß wie viele Einträge ich benötige, wird die Array dynamisch verwaltet, d. h. kommt ein neuer Eintrag dazu, wird er hinzugefügt, wird ein Eintrag nicht mehr benötigt, bekommt er zuerst einen Delete Vermerkt. Erst auf Anweisung wird das Array dann bereinigt. Dazu habe ich die untere Funktion.

Unabhängig davon ob die Funktion effektiv ist, bringt sie gelegentlich, nicht immer, einiges durcheinander. Nur erkenne ich kein Muster. Irgendwann sind einige Infos durcheinander, aber nie alles. Wo liegt der Fehler?

Delphi-Quellcode:
type
  TInfo = record
    Textinfo: Integer;
    Bmp: TBitmap;
    Delete: Boolean;
  end;

var
  Info: array of TInfo;

procedure ClearArray;
var
  i, k: Integer;
begin
  for i := High(Info) downto 0 do
  begin
    if Info[i].Delete then
    begin
      if i = High(Info) then //Ausnahme für High(Info)
      begin
        Info[High(Info)].Bmp.Free;
        SetLength(Info, Length(Info) - 1);
        Continue;
      end;

      for k := i to High(Info) - 1 do //Rest
      begin
        Info[k].Textinfo := Info[k+1].Textinfo;
        Info[k].Bmp.Assign(Info[k+1].bmp);
        Info[k].Delete := Info[k+1].Delete;
      end;
      Info[High(Info)].Bmp.Free;
      SetLength(Info, Length(Info) - 1);
    end;
  end;
end;
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#2

AW: Funktion kommt beim sortieren des Array durcheinander

  Alt 16. Feb 2012, 18:41
Die Art und Weise, wie du den Record kopierst ist "ungünstig".
Besser man vermeidet permanente Zuweisungen mit Assign:
Delphi-Quellcode:
procedure MoveInfoRecord(var src, dst:TInfo);
begin
  dst.Textinfo := src.Textinfo;
  dst.Bmp := src.bmp); // nur den Objektzeiger kopieren
  dst.Delete := src.Delete;
end;


procedure ClearArray;
var
  i, k: Integer;
begin
  for i := High(Info) downto 0 do
  begin
    if Info[i].Delete then
    begin
      // zuerst Bitmap freigeben
      Info[i].Bmp.Free;
      // der Platz i ist jetzt quasi ungültig

      // jetzt die gültigen Daten "runterschieben"
      for k := i to High(Info) - 1 do //Rest
      begin
        MoveInfoRecord(Info[k+1], Info[k]);
      end;
      // Array um 1 verkürzen
      SetLength(Info, Length(Info) - 1);
    end;
  end;
end;
Andreas
  Mit Zitat antworten Zitat
Popov
(Gast)

n/a Beiträge
 
#3

AW: Funktion kommt beim sortieren des Array durcheinander

  Alt 16. Feb 2012, 19:13
Die Art und Weise, wie du den Record kopierst ist "ungünstig".
Besser man vermeidet permanente Zuweisungen mit Assign:
Ja, das habe ich auch so gesehen, deshalb meinte ich auch, dass sie ineffektiv ist (irgendwie ist es das erste Mal, dass ich Objekte über Array sortiere). Mein erster Gedanke war auch die Zuweisung über Adressen, nur hatte ich einen Gedankenfehler, dass wenn ich alles runterkopiere und dann zuletzt die Adresse freigebe... Und das war der Dedankenfehler, die Reihenfolge. Also vielen Dank für den Tipp.

Ansonsten kommen die Daten immer noch durcheinander. Nur wenn das nicht hier ist, dann muß ich den Fehler wo anders suchen.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#4

AW: Funktion kommt beim sortieren des Array durcheinander

  Alt 16. Feb 2012, 19:14
[edit]
war falsch ... bis gleich
$2B or not $2B
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#5

AW: Funktion kommt beim sortieren des Array durcheinander

  Alt 16. Feb 2012, 19:53
Nur wenn das nicht hier ist, dann muß ich den Fehler wo anders suchen.
Schreib Dir doch ein kleines Testprogramm, dass einige Einträge ins Array macht, dann ein paar Einträge zum Löschen markiert und zum Schluss wird ClearArray aufgerufen.

Du testet damit deinen eigenen Programmcode isoliert vom restlichen Programm.
Man nennt diese Vorgehensweise auch Unit-Testing.
Andreas
  Mit Zitat antworten Zitat
Bjoerk

Registriert seit: 28. Feb 2011
Ort: Mannheim
1.384 Beiträge
 
Delphi 10.4 Sydney
 
#6

AW: Funktion kommt beim sortieren des Array durcheinander

  Alt 16. Feb 2012, 19:57
Das mit dem "Rest" hab' ich nicht verstanden, aber rauslöschen geht so (ungetestet)

Delphi-Quellcode:
procedure DelItem(const Index: integer);
var
  I: integer;
begin
  for I:= Index to Length(Info)-2 do
    Info[I]:= Info[I+1];
  Info[Length(Info)-1].Bmp.Free;
  SetLength(Info, Length(Info)-1);
end;

procedure ClearArray;
var
  I: Integer;
begin
  I:= 0;
  while I < Length(Info) do
  begin
    if Info[I].Delete then
    begin
      DelItem(I);
      Dec(I);
    end;
    Inc(I);
  end;
end;

end.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#7

AW: Funktion kommt beim sortieren des Array durcheinander

  Alt 16. Feb 2012, 20:07
Einfachen und sicheren Trick Tipp:

Leite dir eine neue Komponente von TBitmap ab und spendiere ihr ein neues Property "TextInfo",
oder erstell dir ein Container-Object für TextInfo und das Bitmap.

Nun alles in eine TObjektList mit OwnsObjects=True und fertig.
$2B or not $2B

Geändert von himitsu (16. Feb 2012 um 22:54 Uhr)
  Mit Zitat antworten Zitat
Iwo Asnet

Registriert seit: 11. Jun 2011
313 Beiträge
 
#8

AW: Funktion kommt beim sortieren des Array durcheinander

  Alt 16. Feb 2012, 22:22
Ich würde das eh anders machen (manchmal die einfachste Möglichkeit, ein Problem zu lösen)
Delphi-Quellcode:
i := Low(Info);
While i<=High(Info) do begin
  if Info[i].Deleted then begin
    MoveInfo(High(Info),i);
    setLength(Info, Length(Info) - 1);
  end;
  inc(i);
end;
Also: Jedes 'Loch' wird einfach mit dem höchsten Element aufgefüllt und die Liste dann verkleinert.
Sofern Du keine sortierte Liste hast, geht das natürlich viel schneller.

Tipp: Verwende die 'Top-Down Programmierung mit Stepwise refinement' Das war vor 30 Jahren, als ich angefangen habe, state of the art. Und ist es immer noch, wenn ich an Refactoring denke und die Prämisse, Code lesbar und kompakt zu halten.
  Mit Zitat antworten Zitat
Popov
(Gast)

n/a Beiträge
 
#9

AW: Funktion kommt beim sortieren des Array durcheinander

  Alt 17. Feb 2012, 00:40
Schreib Dir doch ein kleines Testprogramm, ...
In der Regel mach ich das auch so, aber die eigentliche Array ist etwas komplexer, auch wenn der Kern des Problems sich auf das Beispiel reduzieren läßt. Wollte es mir sparen. Kommen wohl nicht drumherum.

@Bjoerk
Danke für das Beispiel. Auch eine Möglichkeit.

@himitsu
Eigene Klasse ist auch eine Möglichkeit, überlege ich auch schon die ganze Zeit. Aber das Programm ist einfach so mitgewachsen, bzw. ist erweitert worden. War am Anfang anders geplant. Aber wenn es nicht anders geht.

@Iwo Asnet
Danke für die Info, werde ich es mir überlegen.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:54 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz