AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi TStringList - Anzahl der Wörter zählen
Thema durchsuchen
Ansicht
Themen-Optionen

TStringList - Anzahl der Wörter zählen

Ein Thema von Go2EITS · begonnen am 27. Aug 2006 · letzter Beitrag vom 3. Okt 2006
Antwort Antwort
Go2EITS

Registriert seit: 25. Jun 2006
519 Beiträge
 
Delphi 7 Personal
 
#1

TStringList - Anzahl der Wörter zählen

  Alt 27. Aug 2006, 13:56
Hallo DP!

Ich wende mich mal wieder mit einer Problemstellung an Euch: Ich habe eine TStingList namens Woerter und AnzWoerter (in die ich die Anzahl/Häufigkeit der Woerter speichern möchte). Ich sehe mit der Function TOLIST(S:String):Boolean; nach, ob der String/das Wort in der Liste
ist und wird eingefügt, wenn es nicht vorhanden ist. jetzt ist der String/das Wort aber schon vorhanden und möchte eigentlich ein Zähler zur Stringliste hinzufügen. Kann ich die TstingList 2 Dimensional erstellen, so dass die Werte nicht durcheinander kommen.
Im Übrigen ist woerter.sorted:=True gesetzt.
Hier mein schrecklicher Code:
Delphi-Quellcode:
Function ToList(const S:String):Boolean;
var i,x:Integer;
flag:Boolean;
index:integer;
begin
result:=false;
// String gefunden, dann Zähler erhoehen.
if woerter.Find(s,index) then
       begin
       X:=StrToInt(Anzwoerter[index]);INC(x);AnzWoerter[index]:=inttostr(x);
       exit;
       end;
// Wenn nichts gefunden wurde:
woerter.Add(s);
// Wir wissen den Index
woerter.Find(s,index);
// Hier der Code der die Liste AnzWoerter durcheinander bringt.
// Wie kann ich die Liste synchronisieren?
anzwoerter.Add('1');
result:=true;
end;
Hat jemand einen Lösungsansatz?
Beste Grüße! Go2EITS
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.858 Beiträge
 
Delphi 11 Alexandria
 
#2

Re: TStringList - Anzahl der Wörter zählen

  Alt 27. Aug 2006, 14:01
Dann würde ich einen Record für die Einträge und diese mit einer eigenen List-Klasse verwalten (bzw. ObjectList)
Markus Kinzler
  Mit Zitat antworten Zitat
Benutzerbild von Jens Schumann
Jens Schumann

Registriert seit: 27. Apr 2003
Ort: Bad Honnef
1.644 Beiträge
 
Delphi 2009 Professional
 
#3

Re: TStringList - Anzahl der Wörter zählen

  Alt 27. Aug 2006, 14:08
Hallo,
Du benötigst nur ein TStringList Objeckt.
Glücklicherweise kann zu jedem Eintrag in TStringList ein Referenz auf ein TObject speichern.
Schau mal in OH unter TStringList.AddObject und TStringList.Objects nach.
In letzter Konsequenz handelt es dabei nur einen Zeiger. Da ein Zeiger aber nichts anderes
als 4 Byte sind kann man dort mit etwas Typcasting auch einen Integerwert speichern.
z.B.sl.AddObject('Wort',TObject(Anzahl)) Mit TObject(Anzahl) kannst Du dem Compiler vergaukeln das es sich um eine Objektreferenz handelt.
Beim Lesen muss Du aber wieder in einen Integer casten
Delphi-Quellcode:
var
  Anzahl : Integer;
...
  Anzahl:=Integer(sl.Objects[aIndex])
I come from outer space to save the human race
  Mit Zitat antworten Zitat
Go2EITS

Registriert seit: 25. Jun 2006
519 Beiträge
 
Delphi 7 Personal
 
#4

Re: TStringList - Anzahl der Wörter zählen

  Alt 27. Aug 2006, 15:12
@Mkinzler
Das mit der TStringlist war praktisch: Der woerter.found-Befehl war 100x schneller als meine Suche in der Liste mit "for i:=1 to Anzahl_Woerter do.." und der "Exit if found" Kombination. Zudem war keine Sortierroutine notwendig, weil die Eigenschaft Sorted schon vorhanden ist. Für den Record müsste ich Quicksort einbauen, wo doch meine Liste doch eigentlich schon fast fertig ist.

@jens Schuman
Also den Integer zu String und zurück habe ich schon drin. Siehe Code. OOP ist nicht so mein Ding.
Das Problem: ich füge das Wort: 'that' in die Liste mit woerter.add ein. Es wird wird automatisch einsortiert. Nun muss ich auch einen Eintrag in AnzWoerter einfügen. Ok. Mache ich mal mit AnzWorter.Add('1'); Es wird am Ende eingefügt. Als Lösungsansatz sehe ich möglicherweise, dass ich den letzen Eintrag in der Liste AnzWoeter nehmen muss und ab INDEX 'That' alle Werte nach oben schiebe damit am INDEX/Position 'that' gesetzt werden kann und meine AnzWoerter wieder die richtigen Werte zu den in Woerter befindlichen Liste passen.

Vielen Dank für Eure Antworten. Ich benötige aber leider noch weitere Überlegungen.
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#5

Re: TStringList - Anzahl der Wörter zählen

  Alt 27. Aug 2006, 15:30
Hi,
ich weiß zwar nicht genau warum OOP nicht dein Ding ist, aber da du nicht etwas generelles gegen Klassen hast (du verwendest ja eine TStringList) solltest du doch die Variante von Jens vorziehen.
An sich ist es natürlich sauberer ein Integer in einem Wrapper auch wirklich als Objekt zu übergeben. Klar, hier eine Referenz eh ein Integer, aber wenn Delphi mal etwas typsicherer wird...

Jedenfalls zeigt dir Jens Lösung, dass du mit einer Liste auskommst. Du hast eine Art Dictonary. Hier wird ein Tupel (Schlüssel, Wert) abgespeichert. Anhand von Schlüssel kannst du dir den gespeicherten Wert zurückgeben lassen. Wird die Liste z.B. sortiert, bleibt diese Zuordnung automatisch erhalten.
Wenn du hier noch ein THashedStringList verwendest (ein Nachfahre der TStringList) dürfte sich auch dir Perfomance noch einmal ordentlich verbessern.
Als einfaches Beispiel:

Delphi-Quellcode:
type
  TIntegerWrapper = class(TObject)
    private
      FValue : Integer;
    public
      Value : Integer read FValue write FValue;
  end;

...

procedure toList(const s : String; const List : TStringList);
var buffer : TIntegerWrapper;
begin
  if assigned(List) then
  begin
    if List.indexOf(s) > -1 then
    begin
      buffer := TIntegerWrapper(List.Objects[List.indexOf(s)]);
      buffer.Value := buffer.Value + 1;
    end

    else
    begin
      buffer := TIntegerWrapper.Create;
      buffer.Value := 1;
     
      List.AddObject(s, buffer);
    end;
  end;
end; // procedure toList(const s : String; const List : TStringList);
Hier siehst du, dass du mit einer Liste auskommst. Es ist jetzt egal was du mit der Liste machst, die Zuordnung String -> Anzahl würde immer erhalten bleiben (beim Einfügen, Löschen, Sortieren, ...). Mittels AddObject legst du einfach an der Stelle des Strings einen Verweis auf ein Objekt ab. Dieser Verweis bleibt immer erhalten. Wie man damit arbeitet hat dir Jens eigentlich schon gezeigt, hier ist einfach nur ein Wrapper zu gegekommen.

Gruß Der Unwissende
  Mit Zitat antworten Zitat
Go2EITS

Registriert seit: 25. Jun 2006
519 Beiträge
 
Delphi 7 Personal
 
#6

Re: TStringList - Anzahl der Wörter zählen

  Alt 3. Okt 2006, 14:53
Ich habe ein wenig studieren müssen, bis verstande habe, was Ihr mir da anbietet.
Den Testcode habe ich mal reingestellt."Property" habe ich dem Code hinzufügt.

Delphi-Quellcode:
type
  TIntegerWrapper = class(TObject)
    private
      FValue : Integer;
    public
     property Value : Integer read FValue write FValue;
  end;

var Form1: TForm1;
VAR w,a:TStringList;
var i:Integer;
var Anzahl : Integer;
implementation

procedure toList(const s : String; const List : TStringList);
var buffer : TIntegerWrapper;
begin
  if assigned(List) then
  begin
    if List.indexOf(s) > -1 then
    begin
      buffer := TIntegerWrapper(List.Objects[List.indexOf(s)]);
      buffer.Value := buffer.Value + 1;
    end
    else
    begin
      buffer := TIntegerWrapper.Create;
      buffer.Value := 1;
      List.AddObject(s, buffer);
    end;
  end;
end; // procedure toList(const s : String; const List : TStringList);
{$R *.dfm}
begin
  w:=TStringList.Create;
  Anzahl:=0;
  Tolist('Das',w);
  for i:=0 to w.count-1 do begin
  ShowMessage(w[i]);
  Anzahl:=Integer(w.objects[i]);
  ShowMessage(IntToStr(anzahl));
  end;
  FreeAndNil(w);
end.
Es klappt leider nicht. Ich bekomme hier nur eine große Zahl, aber keine 1.
Ich gehe davon aus, das ich auch ein int64 nehmen kann.
  Mit Zitat antworten Zitat
Hawkeye219

Registriert seit: 18. Feb 2006
Ort: Stolberg
2.227 Beiträge
 
Delphi 2010 Professional
 
#7

Re: TStringList - Anzahl der Wörter zählen

  Alt 3. Okt 2006, 15:14
Hallo Go2EITS,

in Objects[] befinden sich die Wrapper-Objekte, keine Integer-Werte:

Anzahl := TIntegerWrapper(w.Objects[i]).Value; Du solltest außerdem nicht vergessen, vor der Freigabe der Stringliste die Wrapper-Objekte freizugeben.

Zitat von Delphi-Hilfe:
Das TStrings-Objekt ist nicht der Eigentümer der Objekte des Arrays Objects. Objekte, die dem Array Objects hinzugefügt werden, sind auch dann noch vorhanden, wenn das TStrings-Objekt freigegeben wird. Sie müssen explizit von der Anwendung freigegeben werden.
Gruß Hawkeye
  Mit Zitat antworten Zitat
Go2EITS

Registriert seit: 25. Jun 2006
519 Beiträge
 
Delphi 7 Personal
 
#8

Re: TStringList - Anzahl der Wörter zählen

  Alt 3. Okt 2006, 15:35
Funzt! Spitze!
Sorry, wie gebe ich das Object frei in meinem Fall. (Null Ahnung hab!)
Heißt dass, ich ein Freeandnil(w.objects) machen muss?
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#9

Re: TStringList - Anzahl der Wörter zählen

  Alt 3. Okt 2006, 15:39
Hallo,

ich finde den TIntegerWrapper hier nicht so gut. Es gehört zu den best practices eines framework designers jeder Klasse eine tag property mitzugeben, wenn diese Klasse keine rein interne Funktion hat. Mal ist diese property eine Integer (Tag), mal ein Pointer (Data) und mal ein TObject. Es wurde jeweils der Typ gewählt, der am sinnvollsten erschien - alle anderen Typen müssen über einen type cast passend gemacht werden. Das ist nichts verwerfliches und es genügt, wenn der type cast geeignet gekapselt wird. Der Wrapper bringt in diesem konkreten Fall Mehraufwand, dem kein Nutzen gegenüber steht.

Delphi-Quellcode:
function GetCount(sl: TStrings; const s: String): Integer;
var
  index: Integer;
begin
  index := sl.IndexOf(s);
  if index < 0
    then Result := 0
    else Result := Integer(sl.Objects[index]);
end;

procedure SetCount(sl: TStrings; const s: String);
var
  index: Integer;
begin
  index := sl.IndexOf(s);
  if index < 0
    then sl.AddObject(s, Pointer(1))
    else sl.Objects[index] := Pointer(Succ(Integer(sl.Objects[index])));
end;

procedure TDemoForm.DemoButtonClick(Sender: TObject);
var
  sl: TStringList;
  i: Integer;
begin
  sl := TStringList.Create;
  sl.Sorted := True;
  sl.Duplicates := dupIgnore;

  SetCount(sl, 'so');
  SetCount(sl, 'oder');
  SetCount(sl, 'So');

  ListBox.Clear;
  for i := 0 to Pred(sl.Count) do
    ListBox.Items.Add(Format('%s = %d', [sl[i], GetCount(sl, sl[i])]));

  sl.Free;
end;
Grüße vom marabu
  Mit Zitat antworten Zitat
Go2EITS

Registriert seit: 25. Jun 2006
519 Beiträge
 
Delphi 7 Personal
 
#10

Re: TStringList - Anzahl der Wörter zählen

  Alt 3. Okt 2006, 15:56
@marabu
Da staune ich aber: Wenn das so ist! Ich habe zu wenig Ahnung mit Wrappern. Das übernehme ich so. Danke für Deine Mühe mir fertigen und funktionierenden Code zu liefern. Das hätte ich nie so hingebracht. Jetzt verstehe ich den Zusammenhang von TStringList und Objects besser.

@Hawkeye219
Nett, dass Du meinen Code durchgesehen hast und mir die Lösung gebracht hattest.

@Der_Unwissende
Vielen Dank für Deine Hilfe und dass Du bei mir immer reinsiehst und Hilfestellung leistest.

Beste Grüße an alle "Helfer."
Go2EITS
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:47 Uhr.
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