Autor Beitrag
Jakob Schöttl
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 929
Erhaltene Danke: 1


Delphi 7 Professional
BeitragVerfasst: Fr 14.07.06 17:51 
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:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
  for n := 0 to ListBox1.Items.Count -2 do
    for i := (n + 1to 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:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
for n := 0 to ListBox1.Items.Count -2 do
    for i := (n + 1to 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 4106
Erhaltene Danke: 13


Delphi 2010 Pro; Delphi.Prism 2011 pro
BeitragVerfasst: 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.

_________________
Markus Kinzler.
Marco D.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2750

Windows Vista
Delphi 7, Delphi 2005 PE, PHP 4 + 5 (Notepad++), Java (Eclipse), XML, XML Schema, ABAP, ABAP OO
BeitragVerfasst: Fr 14.07.06 21:46 
ausblenden 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 ;)

_________________
Pascal keeps your hand tied. C gives you enough rope to hang yourself. C++ gives you enough rope to shoot yourself in the foot
Blackheart666
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2195

XP
D3Prof, D6Pers.
BeitragVerfasst: Fr 14.07.06 23:30 
ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 929
Erhaltene Danke: 1


Delphi 7 Professional
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 4106
Erhaltene Danke: 13


Delphi 2010 Pro; Delphi.Prism 2011 pro
BeitragVerfasst: 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.

_________________
Markus Kinzler.
Jakob Schöttl Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 929
Erhaltene Danke: 1


Delphi 7 Professional
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 4106
Erhaltene Danke: 13


Delphi 2010 Pro; Delphi.Prism 2011 pro
BeitragVerfasst: 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.

_________________
Markus Kinzler.