Entwickler-Ecke
Algorithmen, Optimierung und Assembler - [TStrings] doppelte Einträge entfernen
Jakob Schöttl - Fr 14.07.06 17:51
Titel: [TStrings] doppelte Einträge entfernen
Hallo,
Ich will aus meiner ListBox alle doppelten einträge entfernen. Zuerst wollte ich folgenden Algorithmus nehmen, also einen zeiger auf einen eintrag, und alle anderen nachfolgenden einträge auf gleichheit überprüfen, wenn gleich löschen:
Delphi-Quelltext
1: 2: 3: 4:
| for n := 0 to ListBox1.Items.Count -2 do for i := (n + 1) to ListBox1.Items.Count -1 do While ListBox1.Items.Strings[n] = ListBox1.Items.Strings[i] do ListBox1.Items.Delete(i); |
Aber da kommt immer der Fehler, dass ich das Maximum überschreite (Exception).
Vielleicht denken sich manche: So ein depp, das ist doch klar, weil der Fehler an meinem Code liegt!
Aber ich weiß leider nicht woran der Fehler liegt. Kann es sein, dass in einer for-Schleife der Endwert, in meinem Fall "ListBox1.Items.Count ...", nicht aktuellisiert wird, sondern immer gleich bleibt?
Ich wollte als alternative folgendes nehmen: alle Duplikate von Einträge werden auf '' gesetzt, und anschließend werden alle '' gelöscht.
Das ist zwar nicht die optimale lösung. Ich wollte es dann also so machen:
Delphi-Quelltext
1: 2: 3: 4:
| for n := 0 to ListBox1.Items.Count -2 do for i := (n + 1) to ListBox1.Items.Count -1 do if ListBox1.Items.Strings[n] = ListBox1.Items.Strings[i] then ListBox1.Items.strings[i] := ''; |
Aber Hilfe!! Nun hängt er in einer Endlos-Schleife! Warum?
Ich hoffe wirklich ihr könnt mir helfen.
mkinzler - Fr 14.07.06 18:08
Zitat: |
Kann es sein, dass in einer for-Schleife der Endwert, in meinem Fall "ListBox1.Items.Count ...", nicht aktuellisiert wird, sondern immer gleich bleibt? |
Ja, deshalb wäre es besser eine downto-Forschelife zu nehmen.
Marco D. - Fr 14.07.06 21:46
Delphi-Quelltext
1: 2: 3:
| for n := listbox1.items.count-2 downto 0 do begin ... |
Der Rest müsste auch noch angepasst werden. Du musst die Liste also nicht von vorne, sondern von hinten durchgehen ;)
Blackheart666 - Fr 14.07.06 23:30
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| procedure TForm1.Button1Click(Sender: TObject); var i,j : integer; begin i := 0; while i <= ListBox1.Items.count - 2 do begin for j := i + 1 to ListBox1.Items.count - 1 do begin if ListBox1.Items[i] = ListBox1.Items[j] then begin dec(i); ListBox1.Items.delete(j); break; end; end; inc(i); end; end; |
Jakob Schöttl - Sa 15.07.06 00:08
Vielen Dank, der QuellText hat gleich funktioniert,
aber eine Frage hab ich zu den beiden Vorschlägen von marco und mkinzler: Wenn man also runterzählt, und es werden mehr als ein Eintrag gelöscht, dann beinhaltet doch die äußere schleife wieder eine Variable, die auf einen String zeigt, der nicht existiert?
mkinzler - Sa 15.07.06 07:06
Zitat: |
aber eine Frage hab ich zu den beiden Vorschlägen von marco und mkinzler: Wenn man also runterzählt, und es werden mehr als ein Eintrag gelöscht, dann beinhaltet doch die äußere schleife wieder eine Variable, die auf einen String zeigt, der nicht existiert? |
Es kommt darauf an, welche Logik verwendet wird. Ich würde wenn eine Übereinstimmung gefunden wird, immer das Vergleichselement löschen, dann ist sichergestellt, das pro Durchlauf immer nur ein Element eleminiert wird. Er entscheidet dann also nur ob das Element mit dem aktuellen Index gelöscht wird oder nicht.
Jakob Schöttl - Sa 15.07.06 07:33
aja, wenn man also nur das 1. Vergleichselement löscht, dann dauert es zwar ein bisschen länger, teoretisch, aber dann gibts wenigstens keine Exceptionen
Danke nochmal!
mkinzler - Sa 15.07.06 07:35
Das dütfte auch nicht länger dauern, da die Anzahl der Schleifenduchläufe und die Anzahl der Deletes gleich bleibt. Ich würde auch nur eine Schleife nehmen und per IndexOf auf doppelte Einträge vergleichen.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!