Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Doppelte Einträge in Array filtern (https://www.delphipraxis.net/102698-doppelte-eintraege-array-filtern.html)

dominikkv 2. Nov 2007 16:00


Doppelte Einträge in Array filtern
 
Hi

Ich suche in einem Array of String (vereinfacht) und bekomme als Ergebnis nen Array of ^String:
Delphi-Quellcode:
SuchErgebnis: Array of ^String;
in diesem können allerdings Einträge doppelt vorkommen.
Ich suche nun die beste (und schnellste!) Möglichkeit doppelte Einträge zu finden.
Soll heißen zum Schluss möchte ich ein
Delphi-Quellcode:
EndErgebnis: Array of ^String
haben der keine doppelten Einträge hat!

Bisher mache ich das so:
Delphi-Quellcode:
var Gefunden: Boolean;
    I, J: Cardinal;
begin
  SetLength(EndErgebnis, 1);
  EndErgebnis[0] := Addr(SuchErgebnis[0]^); // SuchErgebnis hat IMMER mindestens einen Eintrag
  for I := 1 to high(SuchErgebnis) do
    begin
      gefunden := false;
      for J := 0 to high(EndErgebnis) do
        if EndErgebnis[J]^ = SuchErgebnis[I]^ then
          begin
            gefunden := True;
            break;
          end;
      if not gefunden then
        begin
          SetLength(EndErgebnis, Succ(Length(EndErgebnis)));
          EndErgebnis[high(EndErgebnis)] := Addr(SuchErgebnis[I]^);
        end;
    end; // for I
end;
Bei 25000 Suchergebnissen dauert das ca 1-2 Sekunden.
Hat jemand ein Optimierungsvorschlag?

mfg.Dominik

Klaus01 2. Nov 2007 16:50

Re: Doppelte Einträge in Array filtern
 
Hallo,

bis Du auf ein Array festgelegt?
Wenn nicht schaut Dir mal die TStringList an, da kannst Du mit
den Optionen "sorted" und "DupIgnore" arbeiten.

Grüße

dominikkv 2. Nov 2007 16:59

Re: Doppelte Einträge in Array filtern
 
hmm bei der StringList muss ich aber mit strings arbeiten und nicht mit pointern, was ich glaube um einiges langsamer ist.

grenzgaenger 2. Nov 2007 17:47

Re: Doppelte Einträge in Array filtern
 
sag mal, ist dein array sortiert? falls nicht, würde ich es dir dringend anraten, dann kannste auch recht perfomant prüfen ob der string enthalten ist und ggf. diesen gar nicht einfügen, oder mit EINEM durchlauf die duplikate entfernen.

im anderen fall, ist deine routine ziemlich optimal... und du wirst dich an die zeiten (und längere) gewöhnen müssen...

FAlter 2. Nov 2007 18:02

Re: Doppelte Einträge in Array filtern
 
Hi,

Zitat:

Zitat von dominikkv
hmm bei der StringList muss ich aber mit strings arbeiten und nicht mit pointern, was ich glaube um einiges langsamer ist.

Ist dir bewusst, wie ein (Ansi/Wide)String Delphi-intern aufgebaut ist? Es handelt sich um einen Zeiger auf das erste Zeichen. Vorher stehen 4 Bytes für die Länge, nach dem letzten Zeichen kommt noch #0. Ein ^String wäre also genaugenommen ein Zeiger auf einen Zeiger (außer bei {$H-}).

Und wenn du a^ := b^ machst, kommst du bestimmt nicht schneller als mit c := d (wobei a und b ^String und c und d normale Strings sind). In deinem Code sehe ich keinen Grund, nicht direkt Strings zu verwenden.

Mfg
FAlter

dominikkv 2. Nov 2007 18:12

Re: Doppelte Einträge in Array filtern
 
ähh ja ist mir klar... nur mein String ist eigendlich ein
Delphi-Quellcode:
String255 = String[255];
und somit
Delphi-Quellcode:
SuchErgebnis, EndErgebnis: Array of ^String255
Sry hätte ich vllt erwähnen sollen... nur ich wollte das so unkompliziert wie möglich machen, damit das verstanden wird.
SuchErgebnis ist darüber hinaus in Wirklichkeit ein String255 in einem Record in einem Record -.-

Ich were mal schauen ob ich die ganzen SetLength in der schleife umgehen kann... vllt bringts ja was

marabu 2. Nov 2007 18:33

Re: Doppelte Einträge in Array filtern
 
Hallo Dominik,

bedenke, dass für jeden ShortString der maximal benötigte Speicherplatz reserviert wird - AnsiStrings sind da viel ökonomischer.

Delphi-Quellcode:
procedure ExtractUniqueStrings(list, result: TStrings);
var
  temp: TStringList;
begin
  temp := TStringList.Create;
  temp.Sorted := True;
  temp.Duplicates := dupIgnore;
  try
    temp.Assign(list);
    result.Assign(temp);
  finally
    temp.Free;
  end;
end;
Grüße vom marabu

dominikkv 2. Nov 2007 18:58

Re: Doppelte Einträge in Array filtern
 
Allerdings brauche ich um Strings in eine Datei zu speichern eine finalization, geht also nur mit ShortStrings.
Ich werde trotzdem mal die StringList ausprobieren... :cheers:


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:26 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-2025 by Thomas Breitkreuz