Einzelnen Beitrag anzeigen

Schwedenbitter

Registriert seit: 22. Mär 2003
Ort: Finsterwalde
622 Beiträge
 
Turbo Delphi für Win32
 
#4

AW: Suche in TStrings optimieren

  Alt 28. Mär 2011, 22:03
Danke für die super Antworten!

@jfheins
Die Sache mit dem Hoch- und Runtergehen hatte ich mir in der Zwischenzeit auch schon überlegt. So elegant wie Du habe ich es leider nicht, aber es klappt auch bei mir (erprobt mit trial and error). Wenn ich Deinen Code richtig lese (mit der Betonung auf wenn), dann hat er einen einzigen Haken: Er geht jedes Mal, wenn ein Fund auftritt, nach oben und nach unten. Wenn man Pech hat, der Benutzer hatte (1) alle Einträge ausgewählt und es gibt (2) jeden Eintrag nur einmal, was (3) zwar nicht gewollt ist, dann bedeutet das selbst im Idealfall immer noch n * 3 (n selbst, 1 oben, 1 unten) Schritte. Mir war auch aufgefallen, dass Du Clients.Items[I] immer mit Clients.Items[J] statt wie ich mit Current vergleichst. Geht das so schneller?
Ich selbst hatte aus diesem Grund bei meinen Überlegungen die For- durch eine While-Schleife ersetzt. Das ganze sieht bei mir jetzt so aus:
Delphi-Quellcode:
  I:=0;
  While (I < Clients.Count) Do
  Begin
    If Clients.Selected[I] Then
    Begin
      SendTo[I]:=True;
      Current:=Clients.Items[I];
      SendList:=SendList + Current + ', ';

      // vor gefundenem Eintrag suchen
      J:=Pred(I);
      While (J >= 0) Do
        If (Clients.Items[J] = Current) Then
        Begin
          SendTo[J]:=True;
          Dec(J);
        End
        Else Break;

      // nach gefundenem Eintrag suchen
      J:=Succ(I);
      While (J < Clients.Count) Do
        If (Clients.Items[J] = Current) Then
        Begin
          SendTo[J]:=True;
          Inc(J);
        End
        Else Break;

      // nach dem letzten gefundenen Eintrag weiter machen
      I:=J;
    End
    Else Inc(I); // <- besonders wichtig! Hatte ich erst vergessen und ewig den Fehler nicht gefunden.
  End;
Den Vorschlag von s.h.a.r.k kann ich leider nicht umsetzen, weil ich keine weiteren Daten als die Nummer in der Liste habe. Diese kommt bereits sortiert vom Server. Ein umsortieren der Benutzer lasse ich nicht zu; ist mir einfach zu aufwendung.
ABER: Das bringt mich auf die Idee, wie man es evtl. nochmals verbessern kann. Indem man nämlich die Liste 2 x durchgeht. Beim ersten mal sammelt man "nur" alle die, die markiert sind in einer 2. TStringList, die ebenfalls sortiert ist und keine doppelten Einträge zulässt. Beim 2. Durchlauf vergleicht man dann einfach mit IndexOf(), ob ein entsprechender Eintrag aus der Originalliste auch in der 2. Liste ist.
Es könnte bloß daran scheitern, dass IndexOf() seinerseits die Liste zumindest teilweise durchgeht und damit der Vorteil wieder futsch ist, wenn viele ausgwählt sind.
Soviel zur Theorie. Die Praxis werde ich morgen mal testen. Vermutlich müsste ich mal größere Listen generieren lassen, um es zu testen.

Danke nochmal, Alex
Alex Winzer
  Mit Zitat antworten Zitat