![]() |
Einträge in Listview / Stringlist vergleichen;Strings zählen
Hallo zusammen,
es ist inzwischen sehr spät und ich hänge seit Stunden an einem Problem: Ich habe eine Stringlist mit einzelnen Wörtern (Tokens); diese Tokens möchte ich nun - sofern identisch - zählen und in ein Listview ausgeben (Token + Frequenz). Leider schaffe ich es weder, im Listview ein Item suchen zu lassen, so dass ich bei einem Neueintrag dann einfach die Frequenz erhöhen könnte (+1), noch schaffe ich es, innerhalb der Ausgangs-Stringlist und in Schleifen die doppelten Tokens zu finden, zu löschen und zu zählen. Folgendes (mit sicherlich inzwischen mehreren Fehlern, die ich auf Grund von Müdigkeit nicht mehr schnalle) habe ich gezimmert: Wie ihr seht, hab ich sogar irgendwann aus Hilfslosigkeit mit Goto-Verweisungen zu arbeiten versucht; aber nicht einmal das klappt mehr ^^
Delphi-Quellcode:
Zweck des Ganzen: Texte in ihre Tokens/Wörter zergliedern und die Wörter in einer Wortliste samt (Gesamt)Frequenz ausgeben.
procedure TForm1.SpeedButton4Click(Sender: TObject);
var untgesamt: integer; untfrequenz: integer; untwort: array of string; listitem: tlistitem; Textinhalt: Tstringlist; tokenlist: TStringlist; i,ii,iii: integer; begin if untfilelist.Items.Count=0 then exit; //if reffilelist.Items.Count=0 then exit; speedbutton1.Enabled:=false; speedbutton2.Enabled:=false; {Jede Datei öffnen Funktion Tokens isolieren Tokens kopieren, falls vorhanden, frequenz erhöhen Tokens ausgeben} Try Textinhalt:= Tstringlist.Create; tokenlist:= tstringlist.create; // UntFileliste abarbeiten for i:=0 to untfilelist.Items.Count -1 do begin //File einlesen textinhalt.LoadFromFile(untfilelist.Items.Strings[i]); // Satzzeichen in Leerzeichen umwandeln textinhalt.Text:=stringreplace(textinhalt.Text,'.',' ',[rfReplaceAll, rfIgnoreCase]); textinhalt.Text:=stringreplace(textinhalt.Text,',',' ',[rfReplaceAll, rfIgnoreCase]); textinhalt.Text:=stringreplace(textinhalt.Text,';',' ',[rfReplaceAll, rfIgnoreCase]); textinhalt.Text:=stringreplace(textinhalt.Text,'!',' ',[rfReplaceAll, rfIgnoreCase]); textinhalt.Text:=stringreplace(textinhalt.Text,'?',' ',[rfReplaceAll, rfIgnoreCase]); textinhalt.Text:=stringreplace(textinhalt.Text,':',' ',[rfReplaceAll, rfIgnoreCase]); textinhalt.Text:=stringreplace(textinhalt.Text,'-',' ',[rfReplaceAll, rfIgnoreCase]); textinhalt.Text:=stringreplace(textinhalt.Text,'"',' ',[rfReplaceAll, rfIgnoreCase]); textinhalt.Text:=stringreplace(textinhalt.Text,'(',' ',[rfReplaceAll, rfIgnoreCase]); textinhalt.Text:=stringreplace(textinhalt.Text,')',' ',[rfReplaceAll, rfIgnoreCase]); textinhalt.Text:=stringreplace(textinhalt.Text,'[',' ',[rfReplaceAll, rfIgnoreCase]); textinhalt.Text:=stringreplace(textinhalt.Text,']',' ',[rfReplaceAll, rfIgnoreCase]); textinhalt.Text:=stringreplace(textinhalt.Text,'<',' ',[rfReplaceAll, rfIgnoreCase]); textinhalt.Text:=stringreplace(textinhalt.Text,'>',' ',[rfReplaceAll, rfIgnoreCase]); textinhalt.Text:=stringreplace(textinhalt.Text,' ', ' ',[rfReplaceAll, rfIgnoreCase]); textinhalt.Text:=stringreplace(textinhalt.Text,' ', ' ',[rfReplaceAll, rfIgnoreCase]); //Geladenes File in Tokens zerlegen untgesamt:= Extractstrings([' '], [','], pchar(textinhalt.text), tokenlist); {Zerlegtes File in Array speichern, allerdings nur jedes Token einmal, zugleich zählen; Lösungsansatz: 1) Wort für Wort durchgehen; 2) bei jedem Wort nach gleichen Ausdrücken suchen; 3) wenn gleich, dann Audruck löschen und Zähler=zähler+1; am Ende direkt in die listbox ausgeben!} for ii:=0 to tokenlist.Count -1 do begin //Token der Liste durchgehen & ablesen untfrequenz := 1; //label Schleife; for iii:= ii+1 to tokenlist.count -1 do begin //Dasselbe Token in der Liste durchgehen und suchen if tokenlist.Names[ii] = tokenlist.names[iii] then begin // wenn gefunden, dann löschen und zählen tokenlist.Delete(iii); untfrequenz:= untfrequenz + 1; //goto Schleife; end else begin //wenn keine gleichen Tokens mehr gefunden werden, dann in Listview abspeichern with untwortliste do begin listitem := items.add; listitem.caption:= tokenlist.names[ii]; listitem.subitems.add(inttostr(untfrequenz)); end; end; //textansicht.Text :=tokenlist.Text //Test Finally Textinhalt.Free; tokenlist.free; end; Wäre für ein paar Tips, wie ich das lösen könnte, sehr dankbar! Schönes WE und danke für Eure Mühe, frieder |
Re: Einträge in Listview / Stringlist vergleichen;Strings zä
Schau mal hier, da habe ich vor kurzem genau das geschrieben:
![]() Du musst nur noch die Ergebnisliste dann in die ListView ausgeben. |
Re: Einträge in Listview / Stringlist vergleichen;Strings zä
1) Hm, danke jaenicke, aber das klappt bei mir so nicht. Mein Problem ist ja, dass ich nur EINE Stringlist habe mit unterschiedlichen Strings. Die sollen in eine neue Stringlist zusammengefasst und mit der Häufigkeit ausgestattet werden. Ich hatte das bisher so versucht, dass ich
- Stringlist1 durchgegangen bin und z.B. WortX zusammenfassen wollte: - Stringlist2 = Stringlist1 (einmalig) - Stringlist2 durchgehen, ob WortX vorhanden; wenn ja, dann einen CounterInteger +1, den gefundenen Eintrag in Stringlist2 löschen und wieder von vorne Stringlist2 durchgehen, solange, bis in Stringlist2 alle WortX-Items gezählt und gelöscht sind. Nur genau das bekomme ich so nicht hin. Ich bekommme (mit dem schon mal geposteten Code) eine Fehlermeldung, dass ich (vermutlich bei der Delete-Anweisung) einen ListCount überfordere. Naja, hoffe, Du oder jemand anderes kann mir nochmal einen TIpp geben. 2) Eine Frage zu Deinem in dem anderen Thread geposteten Code:
Delphi-Quellcode:
Ich wusste nicht, dass man einem TString ein "Object" beifügen kann; ich kenne diese Methode (als Anfänger) noch nicht; ich bin nur verwundert, weil ich dachte, dass man in einem TString eben nur 1 String, und zwar Zeile für Zeile fassen könnte.
procedure CountOccurrences(const List1, List2: TStrings; var Result: TStrings);
var i, CurIndex: Integer; begin for i := 0 to List1.Count - 1 do Result.AddObject(List1[i], TObject(0)); for i := 0 to List2.Count - 1 do begin CurIndex := Result.IndexOf(List2[i]); if CurIndex >= 0 then Result.Objects[CurIndex] := TObject(Succ(Integer(Result.Objects[CurIndex]))); end; end; Ich würd den Code gerne verstehen :) Danke und viele Grüße zum Samstag, frieder |
Re: Einträge in Listview / Stringlist vergleichen;Strings zä
Zitat:
Der einzige Unterschied ist, dass du die selbe Liste 1 durchgehen musst. Die von dir beschriebene Vorgehensweise ist ebenfalls identisch zu meiner, nur dass ich in der ersten Liste nichts lösche. Wofür auch, ich gehe einfach alle Einträge durch und suche nach jedem in der Ergebnisliste. Zitat:
So kannst du eine bestimmte Information zu jedem String speichern, in diesem Fall eben die Anzahl der Vorkommen in der ersten Liste. |
Re: Einträge in Listview / Stringlist vergleichen;Strings zä
Hey thx,
ABER :) Problem: Wenn ich deinen Code so mache und - da ich ja nur eine Stringlist habe, sie in eine andere kopiere und - beide an deine Countoccurence-Proc übergebe, dann passiert folgendes: Stringlist beinhaltet: eins zwei drei zwei eins Ergebnis: eins: 2 zwei: 2 drei: 1 zwei: 0 eins: 0 Das liegt daran, dass in der kopierten Stringlist ja auch alles doppelt vorhanden ist. - Und jetzt fällt mir gerade ein, was ich tun könnte, dass es dennoch geht: Ich lösche die doppelten Einträge in dieser kopierten Stringlist heraus! :) Nicht sehr elegant. Vielleicht weißt Du was besseres? Danke und gruß, frieder |
Re: Einträge in Listview / Stringlist vergleichen;Strings zä
Ok, wie wäre es so (Zum Testen eine ListBox und ein Button): ;-)
Delphi-Quellcode:
procedure TForm149.Button1Click(Sender: TObject);
procedure CountOccurrences(const MyList: TStrings; var Result: TStrings); var i, CurIndex: Integer; begin for i := 0 to MyList.Count - 1 do begin CurIndex := Result.IndexOf(MyList[i]); if CurIndex >= 0 then Result.Objects[CurIndex] := TObject(Succ(Integer(Result.Objects[CurIndex]))) else Result.AddObject(MyList[i], TObject(1)); end; end; var TempList: TStrings; i: Integer; begin TempList := TStringList.Create; try CountOccurrences(ListBox1.Items, TempList); for i := 0 to TempList.Count - 1 do ShowMessage(TempList[i] + ': ' + IntToStr(Integer(TempList.Objects[i]))); finally TempList.Free; end; end; |
Re: Einträge in Listview / Stringlist vergleichen;Strings zä
Wieso übergibst Du Result als var-Parameter?
|
Re: Einträge in Listview / Stringlist vergleichen;Strings zä
Yepp, das funtzt. Unfair ;)
Danke und Gruß, frieder |
Re: Einträge in Listview / Stringlist vergleichen;Strings zä
Lass das var mal weg, sollte trotzdem funktionieren.
|
Re: Einträge in Listview / Stringlist vergleichen;Strings zä
Klar tut es das, aber mit dem var sieht man klar, dass in diese Variable etwas reingelegt wird. Und deshalb bevorzuge ich diese Schreibweise. Die andere bekommt das const, weil diese nicht verändert wird.
Durch diese Schlüsselwörter sieht man sehr viel besser wie man eine fremde Methode benutzt finde ich. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 19: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