![]() |
Duplikate in Stringlist
Hi, ich benutze diesen Algorithmus um Duplikate in einer Stringlist zu löschen, allerdings braucht dieser extrem lange bei 100.000 Einträgen und mehr.
Kennt jemand einen schnelleren?
Delphi-Quellcode:
procedure KillDuplicates(s: TStrings);
var iLow, iHigh: integer; begin for iLow := 0 to s.Count - 1 do for iHigh := Pred(s.Count) downto Succ(iLow) do if s[iLow] = s[iHigh] then s.Delete(iHigh); end; |
AW: Duplikate in Stringlist
Guten Abend,
darst Du die Liste sortieren, oder sollen alle Einträge in der Reihenfolge beibehalten werden? Grüße Klaus |
AW: Duplikate in Stringlist
Besser wäre es das Einfügen von doppelten Einträgen zu verhindern.
|
AW: Duplikate in Stringlist
Darfst Sortiert werden
|
AW: Duplikate in Stringlist
Zitat:
Zitat:
Klaus |
AW: Duplikate in Stringlist
Wenn ich das mache Mkinzler, dann muss ich doch bei jeden Eintrag neu abfragen, ob dieser in der Liste existiert oder nicht, dann geht die Bearbeitungszeit ebenfalls nach oben, bei 100.000 und mehr Einträgen.
Oder versteh ich das falsch? |
AW: Duplikate in Stringlist
Ja, den eine Tlist hat diese Funktionalität schon (siehe Beitrag von Klaus)
|
AW: Duplikate in Stringlist
Ah so?
StringList.Duplicates := dupError; Und dann mit Except anfangen? |
AW: Duplikate in Stringlist
dupIgnore wäre besser
|
AW: Duplikate in Stringlist
Ich glaube, das geht nur in Verbindung mit "Sorted" oder?
Das funktioniert:
Delphi-Quellcode:
Ohne "Sorted := true;" geht es nicht.
var
sl: TStringList; begin sl := TStringList.Create; try sl.Duplicates := dupIgnore; sl.Sorted := true; sl.Add('a'); sl.Add('b'); sl.Add('a'); ShowMessage(sl.Text); finally FreeAndNil(sl); end; end; Nachtrag: Ah, das steht in Klaus' Zitat am Ende, sehe ich gerade "Duplicates does nothing if the list is not sorted." :wall: |
AW: Duplikate in Stringlist
Super danke
|
AW: Duplikate in Stringlist
Ja, das steht aber auch schon in Klaus' Beitrag
Alternativ könnte man mit .IndexOf() auf Vorhandensein prüfen; ist aber langsamer funktioniert aber auch unsortiert |
AW: Duplikate in Stringlist
Wenn in einer Liste aber bereits vorhandene Duplikate stehen (so wie im ursprünglichen Posting angegeben) würde ich die Liste kopieren, dies sollte bedeutend schneller gehen als das Prüfen mit deiner Routine:
Nur so hingetippt ohne zu überprüfen obs auch funktioniert
Delphi-Quellcode:
var
sl1, sl2:TSTringlist; i:Integer; t_start, t_stop:integer; iLow, iHigh: integer; begin sl1:= Tstringlist.Create; sl2:=TStringlist.Create; try sl1.loadfromFile('c:\temp\testfîle.lst'); //laden einer Stringliste //Variante mit neuer Stringliste sl2.Duplicates:= dupignore; sl2.Sorted:=true; t_start := gettickcount; sl2.Assign(Sl1); //Einträge der zweiten Stringliste zuordnen t_stop := gettickcount; showmessage('Variante1; ' +inttostr(t_stop - t_start)+ ' ms'); //Variante2 kopiert aus dem Originalposting t_start := gettickcount; for iLow := 0 to sl1.Count - 2 do for iHigh := Pred(sl1.Count) downto Succ(iLow) do if sl1[iLow] = sl1[iHigh] then sl1.Delete(iHigh); t_stop := gettickcount; showmessage('Variante2: ' +inttostr(t_stop - t_start)+ ' ms'); finally sl1.Free; sl2.Free; end; |
AW: Duplikate in Stringlist
Eine Hashmap prüft das Vorhandensein eines Strings wesentlich effektiver, als das in der TStringList eingebaute 'Duplicates'. Beim Einfügen dürfte das die bei weitem schnellste Möglichkeit sein.
Du kannst Dir auch die THashedStringList aus der Unit 'IniFiles' nehmen, die hier vielleicht auch schnell genug sein könnte. |
AW: Duplikate in Stringlist
Habe noch eine Frage.
Ich hab nun 2 Stringlisten. 1. Duplikate die nicht in die neue Strinlit aufgenommen werden soll und 2. die neue Stringlist.
Delphi-Quellcode:
Habe also "sOld" = Duplikate die nicht in die neue Stringlist "s" aufgenommen werden sollen.
Try
sOld.Duplicates := dupError; sOld.Sorted := true; sOld.Add(url); // Abgleich Stringlist s.Add(url); // Neu Link Stringlist except on EStringListError do end; Allerdings funktioniert das auch, jedoch statt 2 Sekunden, normaler ab Arbeitungszeit, der Procedure nun 9-15 Sekunden, nur durch diesen Codeteil. |
AW: Duplikate in Stringlist
Wie gesagt ist es besser dupIgnore zu setzen. Denn so wird ja bei jedem doppelten Vorkommen eine Exception ausgelöst!
dupError benötigst du nur, wenn du auf dies in irgendeiner Form reagieren willst. Btw.: das mit dem Delphi-Tag statt Code-Tag gilt für alle Beiträge |
AW: Duplikate in Stringlist
Das Problem bei Dupignor ist allerdings nun das ich in der Stinglist "s" keine Einträge aus der Stringlist sOld haben möchte, sowie die duplikate aus der sOld.
Daher hab ich dies mit einer Exception versucht zulösen, da dann ja "s.add()" übersprungen wird sobald in sOld ein Duplikat eingetragen werden sollte. |
AW: Duplikate in Stringlist
Rate mal was dupIgnore macht? Oder schau in der Hilfe nach.
|
AW: Duplikate in Stringlist
Ich weiß schon was dupignore macht, aber ich habe 2 Stringlisten.
Eine mit duplikaten und eine leere und in der leeren sollen auch keine duplicate aus der 1. eingeführt werden. Das heißt ich muss ja testen ob ein duplikate in der 1. eingefügt werden sollte, wenn ja füge es nicht in die 2. Liste ein. Nur weiß ich nicht wie ich das anders als über die exception in Erfahrung bringe. |
AW: Duplikate in Stringlist
Delphi-Quellcode:
if sOld.IndexOf( url) = -1 then
s.Add(url); // Neu Link Stringlist |
AW: Duplikate in Stringlist
Super funktioniert, kostet allerdings immernoch etwas Performance statt 9-15 Sekunden, sind es nun 3 Sekunden von damals 2 - 2,6 Sekunden.
Schneller wird es nicht möglich sein oder? |
AW: Duplikate in Stringlist
Möglicherweise mit einer THashedStringList
|
AW: Duplikate in Stringlist
Ok gerade mit größeren Datensätzen probiert mit IndexOf und bei sovielen Datensätzen wie ich in der Liste haber, dauert das 20-40 Sekunden.
Das ist einfach nicht tragbar. |
AW: Duplikate in Stringlist
Zitat:
|
AW: Duplikate in Stringlist
Soeben mit THashedStringList probiert und das gab wirklich einen extremen Performance boost.
|
AW: Duplikate in Stringlist
Moin,
Zitat:
Eine HashedStringList (wenn das sowas ähnliches ist wie eine Hashmap ist), hingegen definiert, wo ein Wert steht, anhand des Inhalts (z.B.). Also wenn du den Text Foo hast, dann weiß er wo das so ungefähr ist. MfG Fabian |
AW: Duplikate in Stringlist
Zitat:
|
AW: Duplikate in Stringlist
Zitat:
EDIT: Unnötige Bemerkung entfernt. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:21 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