Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Zwei Stringlisten miteinander vergleichen. Wie am besten ? (https://www.delphipraxis.net/124574-zwei-stringlisten-miteinander-vergleichen-wie-am-besten.html)

HolgerCW 21. Nov 2008 09:21


Zwei Stringlisten miteinander vergleichen. Wie am besten ?
 
Hallo zuasmmen,

wie kann ich am besten zwei Stringlisten miteinander vergleichen ?

Gruss

Holger

nahpets 21. Nov 2008 09:35

Re: Zwei Stringlisten miteinander vergleichen. Wie am besten
 
Hallo,

von beiden 'ne MD5-Summe bilden, dann sind sie gleich oder nicht.

Oder brauchst Du Informationen über die Unterschiede?

Sortieren und zeilenweise vergleichen.

In 'ner Schleife durch die erste Liste gehen und mit IndexOf in der zweiten Suchen, wenn IndexOf > -1 in beiden Liste löschen, was über bleibt ist sind die Unterschiede.

DeddyH 21. Nov 2008 09:37

Re: Zwei Stringlisten miteinander vergleichen. Wie am besten
 
Für eine reine Gleichheitsabfrage müsste auch CompareMem() gehen.

HolgerCW 21. Nov 2008 09:43

Re: Zwei Stringlisten miteinander vergleichen. Wie am besten
 
Ich brauche beides. Als erstes wird geprüft ob der Count unterschiedlich ist. Dann baucht auch ncciht mehr verglichen werden. Wenn der Count gleich ist, muss der Inhalt noch verglichen werden. Wie baue ich so eine For-Schleife am besten auf (Performance) ?

Wie nutzt man CompareMem() ?

nahpets 21. Nov 2008 09:49

Re: Zwei Stringlisten miteinander vergleichen. Wie am besten
 
Zitat:

Zitat von DeddyH
Für eine reine Gleichheitsabfrage müsste auch CompareMem() gehen.

oder auch
Delphi-Quellcode:
if StringListe1.Text = StringListe2.Text then ShowMessage('Sindsichgleich')
Wie groß sind die Listen und was musst Du in Bezug auf Unterschied wissen?
Reicht es, wenn Du weißt, dass es einen Unterschied gibt oder musst Du die Unterschiede auflisten...
Ist die Reihenfolge von Bedeutung?
Wenn nein:
Delphi-Quellcode:
StringListe1.Sort;
StringListe2.Sort;
bSindgleich := True;
For i := 0 to StringListe1.Count - 1 Do Begin
  bSindGleich := StringListe1[i] = StringListe2[i];
  if not bSindGleich then break;
end;
Ist die Reihenfolge von Bedeutung, dann ohne Sort.

DeddyH 21. Nov 2008 09:50

Re: Zwei Stringlisten miteinander vergleichen. Wie am besten
 
Mal aus dem Hut:
Delphi-Quellcode:
Gleich := CompareMem(PChar(sl1.Text),PChar(sl2.Text),Length(sl1.Text));

HolgerCW 21. Nov 2008 09:52

Re: Zwei Stringlisten miteinander vergleichen. Wie am besten
 
Hi,

es geht um eine reine Abfrage ob der Inhalt gleich ist.

Beispiel: ST1 hat A,B,C und ST2 hat C,A,B -> sindgleich
Beispie2: ST1 hat A,B,C und ST2 hat A,B,D -> sind ungleich

Geht das mit CompareMem ?

taaktaak 21. Nov 2008 09:56

Re: Zwei Stringlisten miteinander vergleichen. Wie am besten
 
neeee

// edit: oder doch?! erst beide sortieren, dann CompareMem()

nahpets 21. Nov 2008 09:58

Re: Zwei Stringlisten miteinander vergleichen. Wie am besten
 
Zitat:

Zitat von DeddyH
Mal aus dem Hut:
Delphi-Quellcode:
Gleich := CompareMem(PChar(sl1.Text),PChar(sl2.Text),Length(sl1.Text));

Was ist, wenn die Zahl der Zeilen übereinstimmt, aber nicht Length(sl1.Text) und Length(sl2.Text)?
Sollte dann wohl vorher geprüft werden.

Also:
Delphi-Quellcode:
If sl1.Count <> sl2.Count then Exit;
If Length(sl1.Text) <> Length(sl2.Text) then Exit;
If sl1.Text <> sl2.Text Then Exit;
und dann in 'ner Schleife oder wirklich per MD5.

Wenn es um sowas wie in Deinem Beispiel geht, dann
Delphi-Quellcode:
sl1.Sort;
sl2.Sort;
if sl1.Text <> sl2.Text then // sind unterschiedlich

DeddyH 21. Nov 2008 10:00

Re: Zwei Stringlisten miteinander vergleichen. Wie am besten
 
Oder erst die Anzahl der jeweils enthaltenen Strings ermitteln und dann in einer Schleife mit IndexOf() vergleichen. Dies dürfte aber nicht die schnellste Methode sein.

[edit]
Zitat:

Zitat von naphets
Was ist, wenn die Zahl der Zeilen übereinstimmt, aber nicht Length(sl1.Text) und Length(sl2.Text)?

In dem Fall erübrigt sich ein weiterer Vergleich, oder? ;) Ich war davon ausgegangen, dass das bereits abgeprüft wurde. [/edit]

Phoenix 21. Nov 2008 10:05

Re: Zwei Stringlisten miteinander vergleichen. Wie am besten
 
Meine Idee:

Klar, erst den Count.

Um das IndexOf von DeddyH hinten raus schneller zu machen: Kopie von der ersten Liste anlegen.

Durch die zweite Liste einmal durchiterieren, und jeden gefunden Eintrag in der zweiten Liste aus der Kopie der Ersten entfernen.
Prinzip:
Code:
for i:=0 to Liste2.Count -1 do
  Kopie.Remove( Kopie.IndexOf( Liste2.[i]));
Findest Du einen Eintrag nicht, kannst Du sofort abbrechen. Und durch das Entfernen aus der Kopie musst Du bereits gefundene Einträge auch nicht erneut anschauen -> IndexOf hat mit jedem Durchlauf weniger Elemente zu prüfen.

taaktaak 21. Nov 2008 10:09

Re: Zwei Stringlisten miteinander vergleichen. Wie am besten
 
Interessante Idee!

Zwischenfrage: Kenne "Remove" nicht :roll:

Ist das eine Methode, die nach D7 eingeführt wurde?
Warum nicht Delete()?
Oder ist das ein Schreibfehler?

DeddyH 21. Nov 2008 10:10

Re: Zwei Stringlisten miteinander vergleichen. Wie am besten
 
Remove ist AFAIK eine Methode von TList. Delete sollte aber genauso gehen.

nahpets 21. Nov 2008 10:12

Re: Zwei Stringlisten miteinander vergleichen. Wie am besten
 
Zitat:

Zitat von DeddyH
Oder erst die Anzahl der jeweils enthaltenen Strings ermitteln und dann in einer Schleife mit IndexOf() vergleichen. Dies dürfte aber nicht die schnellste Methode sein.

[edit]
Zitat:

Zitat von naphets
Was ist, wenn die Zahl der Zeilen übereinstimmt, aber nicht Length(sl1.Text) und Length(sl2.Text)?

In dem Fall erübrigt sich ein weiterer Vergleich, oder? ;) Ich war davon ausgegangen, dass das bereits abgeprüft wurde. [/edit]

Wenn nach 'nem Sort sl1.Text und sl2.Text ungleich sind, dann könnte IndexOf schnell sein, wenn man beim ersten Unterschied aussteigt, man müsste sonst ja in 'ner Schleife die an gleicher Position miteinander vergleichen, ob das schneller ist, müsste man mal testen. Aber da stellt sich dann die Frage, wieviel Aufwand darf oder muss man Treiben. Listen mit 10 Einträgen oder Listen mit 10.000.000 Einträgen?

Remove heißt Delete. Hatte ich sowas nicht oben schon mal beschrieben? :wink:

DeddyH 21. Nov 2008 10:15

Re: Zwei Stringlisten miteinander vergleichen. Wie am besten
 
Ich bin gerade nicht unter Windows unterwegs und kann daher nicht nachsehen, aber AFAIR ist der Unterschied zwischen Remove und Delete der Rückgabewert (Index bzw. Inhalt). Ich kann mich da aber auch irren.

HolgerCW 21. Nov 2008 10:21

Re: Zwei Stringlisten miteinander vergleichen. Wie am besten
 
Hi.

So sieht es nun bei mir aus:

Delphi-Quellcode:
function ...
begin
 
 Result := FALSE;

 TStringList(aktuelle_StringList).Sorted := true;
 TStringList(alte_StringList).Sorted := true;

 if alte_StringList.Count <> aktuelle_StringList.Count then
 begin

  //Result := CompareMem(PChar(alte_StringList.Text),PChar(aktuelle_StringList.Text),Length(alte_StringList.Text));

  for I := 0 to aktuelle_StringList.Count -1 do
   alte_StringList.Delete(alte_StringList.IndexOf(aktuelle_StringList[i]));

 end else
 begin

  Result := FALSE;

 end;

 alte_StringList.Assign(aktuelle_StringList);
 aktuelle_StringList.Free;

end;
Wie springe ich dort nun beim nicht finden raus oder breche ab ?

Phoenix 21. Nov 2008 10:24

Re: Zwei Stringlisten miteinander vergleichen. Wie am besten
 
Deswegen hab ich "Prinzip" geschrieben und das Teil in Code- und nicht Delphi-Tags gesetzt ;-)
In der .NET Welt heisst das Ding auf Listen eben Remove, und ich bin zur Zeit meist im .NET Umfeld unterwegs *g*
Zumal ich da eh nicht for i.. sondern eine for-in-Schleife nehmen würde ;-)

HolgerCW 21. Nov 2008 10:51

Re: Zwei Stringlisten miteinander vergleichen. Wie am besten
 
Wie springe ich dort nun beim nicht finden raus oder breche ab ?

Phoenix 21. Nov 2008 10:55

Re: Zwei Stringlisten miteinander vergleichen. Wie am besten
 
In etwa so:
Delphi-Quellcode:
var
  foundIndex: integer;
begin
// ...
result := false;

if alte_StringList.Count <> aktuelle_StringList.Count then
begin

  for I := 0 to aktuelle_StringList.Count -1 do
  begin
    foundIndex := alte_StringList.IndexOf(aktuelle_StringList[i]);
    if foundIndex < 0 then
      exit;
    alte_StringList.Delete(foundIndex);
  end;
 
  // alles gefunden?
  result := alte_StringList.Count = 0;

end;
//...

nahpets 21. Nov 2008 11:30

Re: Zwei Stringlisten miteinander vergleichen. Wie am besten
 
Hallo,
Delphi-Quellcode:
function ...
Var
      iIndex : Integer;
begin
  Result := true;
  // Gleiche Zeilenzahl ist nicht zwingend gleichbedeutend mit gleichem Inhalt!!!
  if alte_StringList.Count <> aktuelle_StringList.Count then begin
    if alte_StringList.Text <> aktuelle_StringList.Text then begin

      // Ist aktuelle_StringList keine Stringliste?
      // warum der Cast?
      // TStringList(aktuelle_StringList).Sorted := true;
      // TStringList(alte_StringList).Sorted := true;
 
      aktuelle_StringList.Sort;
      alte_StringList.Sort;

      // Hier wird geprüft, ob alles aus Aktuelle auch in Alte ist.
      // Es wird nicht geprüft, was in Alte ist, aber nicht in Aktuelle.
      for I := 0 to aktuelle_StringList.Count -1 do begin
        // Wenn nicht gefunden ist IndexOf = -1, gibt einen Fehler, wenn er im Delete steht.
        iIndex := alte_StringList.IndexOf(aktuelle_StringList[i]);  
        if iIndex > -1 then alte_StringList.Delete(i)
        else begin // ein Unterschied gefunden
          Result := False;
          break;
        end;
      end;
      // Ist Alte hier nicht leer, dann gibt es in Alte etwas, was nicht in Aktuelle enthalten ist.
      if not Result and (alte_StringList.Count <> 0) do begin
        Result := False;
      end;
      alte_StringList.Assign(aktuelle_StringList);
    end;
  end;
  aktuelle_StringList.Free;
end;

DeddyH 21. Nov 2008 11:33

Re: Zwei Stringlisten miteinander vergleichen. Wie am besten
 
Noch' n Gedicht :mrgreen:
Delphi-Quellcode:
function SameContent(const FirstList, SecondList: TStrings): Boolean;
var i, iIndex: integer;
    tempList: TStringList;
begin
  Result := FirstList.Count = SecondList.Count;
  if Result then
    begin
      tempList := TStringlist.Create;
      try
        tempList.Assign(SecondList);
        i := 0;
        while Result and (i < FirstList.Count) do
          begin
            iIndex := tempList.IndexOf(FirstList[i]);
            if iIndex < 0 then
              Result := false
            else
              tempList.Delete(iIndex);
            inc(i);
          end;
      finally
        tempList.Free;
      end;
    end;
end;

HolgerCW 21. Nov 2008 13:10

Re: Zwei Stringlisten miteinander vergleichen. Wie am besten
 
Vielen dank.

Ihr habt mir wie immer super geholfen.

Gruss

Holger


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:28 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