![]() |
Wörter zählen, optmimieren?
Hallo,
ich möchte die Wörter in einem Rtf-Feld zählen. Dazu habe ich folgenden Code verwendet (s.auch ![]() Es funktioniert ja eigentlich auch, aber nur unheimlich langsam. Auch die schnellere Variante, die nur auf Leerzeichen prüft, ist bei Texten größer als 100KByte zu langsam (ab 300KByte Text wirds richtig lahm). In Word oder Works gibt es auch so eine Funktion, nur dort ist diese blitzschnell. Hat jemand Optimierungsvorschläge oder andere meth. Ansätze?
Delphi-Quellcode:
[edit=Daniel B]Delphi-Tags korrigiert. Mfg, Daniel B[/edit]
function TEditor.CountWordsSlow(minwordlength:Integer):Integer;
var s: string; c: char; i, l, le:Integer; begin i:=0; le:=Length(Text); s:=''; if le > 0 then for l:=1 to le do begin c:=Text[l]; if (Upcase(c) in ['A'..'Z','Ä','Ö','Ü','ü','ö','ä','ß']) then s:=s+c else begin if (Length(s) >= minwordlength) Then Inc(i); s:=''; end; end; CountWordsSlow:=i; end; {TEditor.CountWords} function TEditor.CountWordsFast(minwordlength:Integer):Integer; var s: string; c: char; pnow, plast,i,l,le:Integer; begin //erste Variante (* i:=0; le:=Length(Text); pnow:=1; plast:=1; if le > 0 then for l:=1 to le do begin if Text[l]=' ' then begin plast:=pnow; pnow:=l; if (pnow-plast) > minwordlength then inc(i); end; end; {for} *) // zweite Variante s:=Text; i:=0; pnow:=1; if Length(s) > 0 then while pnow > 0 do begin pnow:=Pos(' ',s); if pnow >= minwordlength then inc(i); Delete(s, 1,pnow); end; //Rest CountWordsFast:=i; end; {TEditor.CountWordsFast} |
Re: Wörter zählen, optmimieren?
Hi,
ich hab gradmal was versucht...
Delphi-Quellcode:
Das ist wahnsinnig langsam... aber diese version:
procedure TForm1.Button1Click(Sender: TObject);
var cnt, i: Integer; begin cnt:=0; for i:=1 to Length(RichEdit1.Text) do if RichEdit1.Text[i] = ' ' then Inc(cnt); ShowMessage(IntToStr(cnt)); end;
Delphi-Quellcode:
ist rasend schnell... bei nem 1mb Text dauert es keine 10tel Sekunde (Also klick auf Button und sofort isses ausgezählt!)
procedure TForm1.Button1Click(Sender: TObject);
var S: String; cnt, i: Integer; begin cnt:=0; S:=RichEdit1.Text; for i:=1 to Length(S) do if S[i] = ' ' then Inc(cnt); ShowMessage(IntToStr(cnt)); end; Hoffe das hilft dir ein wenig :) Au'revoir, Aya~ |
Re: Wörter zählen, optmimieren?
Zitat:
Danke. :P :lol: |
hmm,
das ist aber arg ungenau ? Wörter könne doch auch durch Kommas etc. getrennt sein oder ?
Ich würd es umgekehrt machen in der abfrage anstatt
Delphi-Quellcode:
if s[i] = ' ' then ..
Delphi-Quellcode:
if not(s[i] in ['a'..'z','A'..'Z']) then ..
|
Re: Wörter zählen, optmimieren?
Das ist aber auch blöd. Was, wenn man ein Dollarzeichen schreibt :shock:
Als Trennzeichen dienen i.d.R. Zeilenumbrüche, Leerzeichen, Kommas, Strichpunkte und Tabs Somit würde das dann etwa so aussehen:
Delphi-Quellcode:
if s[i] in [#9,#10,#13,#32,',','.',';'] then //...
Aufpassen muss man aber bei Trennstrichen vor Zeilenumbrüchen, denn das sind dann meist Silbentrennungszeichen. Befindet sich direkt vor einem Zeilenumbruch ein Minus-Strich(-), trennt der Zeilenumbruch das Wwort nicht. Die Bedingung also folgendermaßen erweitern:
Delphi-Quellcode:
if s[i] in [#9,#10,#13,#32,',','.',';']) then
if (s[i] = #13) and (s[i-1] <> '-') then //jetzt ein Wort |
hmm,
ist allgemein schwierig weil es ist wie mit der deutschen Sprache, es gibt x Ausnahmen und Spezialfälle.
Also ich hab ein wenig Syntaxhighlighting versucht zu machen, gibt auch ein Posting dazu irgendwo hier, wie auch immer. Das parsen ist gar nicht so einfach. Schade dass Delphi keine reg. Expressions von Haus aus unterstützt, das ist einfach eine feine Sache (php,ruby,perl loben muss). |
Re: Wörter zählen, optmimieren?
Hi,
Zitat:
Ich dachte anfangs die Performanceeinbußen kamen durch die Mengenoperationen In [...]. Deshalb hatte ich einen anderen, schnelleren (und wie du zurecht bemerkst) äußerst ungenauen Ansatz gewählt (CountWordsFast). Wirklich schneller lief der auch nicht. Gruß Dirk |
Re: Wörter zählen, optmimieren?
Moin Dirk,
bei jeder Art Stringliste, eben auch RichEdit.Lines, wird die Eigenschaft Text bei jedem Lesezugriff auf diese Eigenschaft aus den gesamten Strings zusammengesetzt, und bei jedem Schreibzugriff werden die Zeilen anschliessend neu aufgebaut. Das ist das, was so auf die Performance drückt. |
Re: Wörter zählen, optmimieren?
[quote="Aya"]Hi,
ich hab gradmal was versucht...
Delphi-Quellcode:
Das ist wahnsinnig langsam... aber diese version:
procedure TForm1.Button1Click(Sender: TObject);
var cnt, i: Integer; begin cnt:=0; for i:=1 to Length(RichEdit1.Text) do if RichEdit1.Text[i] = ' ' then Inc(cnt); ShowMessage(IntToStr(cnt)); end;
Delphi-Quellcode:
Hier habe ich aber das Problem, dass auch Leerzeichen mitgezählt werden. Ich habe den Quelltext vollgender Maßen ergänzt:
procedure TForm1.Button1Click(Sender: TObject);
var S: String; cnt, i: Integer; begin cnt:=0; S:=RichEdit1.Text; for i:=1 to Length(S) do if S[i] = ' ' then Inc(cnt); ShowMessage(IntToStr(cnt)); end;
Delphi-Quellcode:
Var i,count:integer; text:string;
Delphi-Quellcode:
count:=0;
Text:=Rich.Text ; for i:=1 to length(Text) do if Text[i]=' ' then if (Text[i+1]<>' ') then inc(count); |
Re: Wörter zählen, optmimieren?
Da mußt du aber wegen dem i+1 und der Länge des Strings aufpassen.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:02 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