Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Stringlist; Häufigkeit einzelner Wörter (https://www.delphipraxis.net/176738-stringlist%3B-haeufigkeit-einzelner-woerter.html)

Mokus 24. Sep 2013 07:48

Delphi-Version: 5

Stringlist; Häufigkeit einzelner Wörter
 
Einen wunder schönen guten Morgen liebe Community,

Ich hätte mal ne frage.
hab schon bisschen rumgestörbert aber noch nicht das ware gefunden, was ich eigentlich gesucht habe.

Meine Aufgabe;
hab ein Memofeld.
Dort wird ein text eingegeben und ich soll die Wörter zählen.
Das war nicht das Problem;
XE2;
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  I: integer;
  st_woerter: tstringlist;
  a_speicher: array of integer;

begin

  st_woerter := tstringlist.create;
  setlength(a_speicher, 2);
  st_woerter.CommaText := Memo1.text;

  for I := 0 to st_woerter.Count - 1 do
  begin
    if st_woerter.CommaText <> '' then
    begin
      a_speicher[0] := a_speicher[0] + 1;
    end;
  end;
  Memo2.text := ('In diesem Text sind es insgesamt: ' + inttostr(a_speicher[0])
    + ' Wörter');

end;

end.
Nun soll ich die Häufigkeit der einzelnen Wörter ausgeben und absteigend Sortieren.
In der Stringlist kann ich mir jedes einzelne Wort rausgeben, aber wie kann ich diese nun öfters Zählen?

Erste überlegung wasr If;
aber soll ich den ganzen Duden in eine if abfrage packen ? :p


Da gibt es bestimmt noch eine andere, vernüftige Möglichkeit.


Dank im vorraus,

Mokus

Klaus01 24. Sep 2013 08:06

AW: Stringlist; Häufigkeit einzelner Wörter
 
Guten Morgen,

bevor Du ein Wort zur StringList addierst kann Du mit TStringList.IndexOf nachschauen ob dieses Wort
schon in der StringList vorhanden ist. Wenn es vorhanden ist, erhöhst Du den Zähler für dieses Wort um eins.
Wenn das Wort nach nicht vorhanden ist, fügst Du es zu StringList hinzu und setzt den Zähler für das Wort auf 1.

Grüße
Klaus

Mokus 24. Sep 2013 08:08

AW: Stringlist; Häufigkeit einzelner Wörter
 
und der Zähler wird ein array, der sich mit jeden neuen wort um einen erhöht...
Das ist eine nette information.

Sollte es noch weiter Fragen geben meld ich mich wieder.

Dank dir Klaus.

DeddyH 24. Sep 2013 08:10

AW: Stringlist; Häufigkeit einzelner Wörter
 
Hallo und Willkommen in der DP :dp:,

eine Möglichkeit, die mir spontan so einfällt: eine zweite Stringliste erzeugen. Bei jedem neuen Wort prüfst Du dann, ob dieses bereits enthalten ist. Wenn ja, zählst Du die Anzahl hoch, wenn nicht, Neueintrag mit Anzahl 1. Für die Anzahl ließe sich die Objects-Property der Liste missbrauchen. Aus der Lameng getippt:
Delphi-Quellcode:
procedure TIrgendwas.CountWord(const NewWord: string);
var
  idx, CurrentCount: integer;
begin
  CurrentCount := 0;
  idx := CountList.IndexOf(NewWord);
  if idx < 0 then
    idx := CountList.AddObject(NewWord, TObject(CurrentCount));
  CurrentCount := integer(CountList.Objects[idx]);
  inc(CurrentCount)
  CountList.Objects[idx] := TObject(CurrentCount);
end;

Mokus 24. Sep 2013 08:47

AW: Stringlist; Häufigkeit einzelner Wörter
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hier noch mal der Delphi anfänger ;-)


Auschnitt 1)
Delphi-Quellcode:
  st_woerter := tstringlist.create;
  st_woerter2 := tstringlist.create;
  setlength(a_speicher, 2);
  st_woerter.CommaText := Memo1.text;
  s_test := st_woerter.CommaText;

Uschnitt 2)

Delphi-Quellcode:
for a := 0 to st_woerter.Count - 1 do
  begin

    I := 0;
    I := st_woerter2.IndexOf(st_woerter[a]);
    showmessage(inttostr(I));
    if I < 0 then
    begin
      index := st_woerter2.AddObject(s_test, TObject(I));
      I := integer(st_woerter2.Objects[index]);
      inc(I);
      st_woerter2.Objects[index] := TObject(I);
    end;
  end;

  Memo2.text := st_woerter2.text;
For schleife weil er ja jedes einzelnes Abgespeichertes Wort kontrollieren soll.
Sonst ist das die gleiche, andere Variablen ok, syntax wie von @DeddyH: ;
nun fällt mir hier aber ja die zähl variable als auch speichert er jedes wort in der stringlist 2 ?!

bitte um Fehler meldung.
( am besten erstmal nur hinweise, fehler suche hilft beim Lernen ;-) )

DeddyH 24. Sep 2013 08:55

AW: Stringlist; Häufigkeit einzelner Wörter
 
Du hast da Dinge vermischt, die getrennt gehören. Meine Routine war dazu gedacht, dass Du ihr jedes Wort aus Deiner Liste übergibst, sie zählt dann selbstständig. Mit der Schleifenvariablen kannst Du ja an der Stelle nichts anfangen. Also etwa so:
Delphi-Quellcode:
CountList := TStringlist.Create;
for a := 0 to st_woerter.Count - 1 do
  CountWord(st_woerter[a]);
Wenn ich keinen Denkfehler gemacht habe, sollten anschließend alle Wörter in CountList enthalten sein und die jeweilige Anzahl als TObject in ihren Objects.

David Martens 24. Sep 2013 09:29

AW: Stringlist; Häufigkeit einzelner Wörter
 
Nur ein paar kleine Hinweise:

Bei XE2 würde ich nicht
Delphi-Quellcode:
array of integer;
benutzen, sonder eher
Delphi-Quellcode:
TList<integer>
oder noch besser
Delphi-Quellcode:
var
  Wortliste : TList<TPair<string, integer>>
begin
  Wortliste := TList<TPair<string, integer>>.Create;
...

  if Wortliste.Item[i].Key = 'Das Wort' then
    Inc(Wortliste.Item[i].Value)
  else
    Wortliste.Add(TPair<string, integer>.Create('Das Wort', 1));
Du kannst auch eine eigene Klasse bei TList angeben.

Auch würde ich dir empfehlen die Wörter vorher zu sortieren (Standartfunktion von TStrings) und dann einfach nur bis zum nächsten unterschiedlichen Wort. Dann mußt du nicht jedesmal die ganze Liste nach einem Wort zu durchsuchen.

David

Blup 24. Sep 2013 09:29

AW: Stringlist; Häufigkeit einzelner Wörter
 
Mal ein anderer Ansatz ohne Countlist.
Delphi-Quellcode:
{
Trennung von Funktion und Oberfläche:
Damit die Funktion überall verwendet werden kann,
werden die Daten und Objekte anonym über Parameter übergeben.
}
procedure GibAnzahlWoerterAus(AList: TStrings; const AText: String);
var
  st_woerter: TStringlist;
  i, n, nGesamt: Integer;
begin
  st_woerter := TStringlist.Create;
  try
    st_woerter.CommaText := Memo1.text;

    {Leerzeichen am Anfang und Ende der Wörter entfernen}
    for i := 0 to st_woerter.Count - 1 do
      st_woerter[i] := Trim(st_woerter[i]);
    {sortieren}
    st_woerter.Sort;

    sWort1  := '';
    n      := 0;
    nGesamt := 0;
    for i := 0 to st_woerter.Count do
    begin
      if i < st_woerter.Count then
        sWort2 := st_woerter[i]
      else
        sWort2 := '';
      {Wort ist unverändert -> Anzahl erhöhen}
      if sWort1 = sWort2 then
        Inc(n)
      else
      begin
        {altes Wort + Anzahl ausgeben, Gesamtsumme anpassen}
        if sWort1 <> '' then
        begin
          AList.Add(IntToStr(n) + 'x ' + sWort1);
          Inc(nGesamt, n);
        end;
        {neues Wort merken und Zähler neu starten}
        sWort1 := sWort2;
        n     := 1;
      end;
    end;
    AList.Add('In diesem Text sind es insgesamt ' + IntToStr(nGesamt) + ' Wörter.');
  finally
    {Objekte die man erzeugt, muss man auch freigeben}
    st_woerter.Free;
  end;
end;

{
In der Ereignisbehandlung werden die konkreten Objekten an die Funktion übergeben,
aber in der Regel wird nur minimale Funktionalität implementiert.
}
procedure TForm1.Button1Click(Sender: TObject);
begin
  Memo2.Lines.Clear;
  GibAnzahlWoerterAus(Memo2.Lines, Memo1.Text);
end;

Mokus 24. Sep 2013 10:39

AW: Stringlist; Häufigkeit einzelner Wörter
 
so;
ein letzte frage hätte ich noch ;

per index of kan ich ja sehen, ob in einer stringlist ein folgender string schon inhalten ist.
kann ich mir in einer if abfrage ausgeben welchen index dieses wort in der liste hat ?

gibt doch bestimmt ein befehl dafür, den ich noch nicht kenn :p

DeddyH 24. Sep 2013 10:42

AW: Stringlist; Häufigkeit einzelner Wörter
 
:?: Genau diesen Index gibt IndexOf ja zurück.


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:34 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz