Autor Beitrag
starsurfer
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 334

Win 95, Win 98, Win XP, Win Vista, Linux
D5 Enterprise ,D2005, D6 Personal, Visual C++ Express 2005, C++ Builder 6 E, Dev-C++
BeitragVerfasst: So 12.02.06 22:02 
Ich schreib garde an nem aufgemotzten Windows Editor.

Und dazu muss ich ja auch in dem Memo nach Wörtern suchen.
Nun bietet ja Richedit eine kleine Funktion die Findtext heist, aber wie ich feststellen musste besitzt Memo die Funktion nicht.

Also hab ich das Internet angeschmissen und hier im Forum gesucht und wieder Erwarten nichts passendes gefunden(Hinweise auf pos() zählen da mit drunter).
Ihr könnt mich natürlich eines Besseren belehren :o

Lange Rede kurzer Unsinn.... hab ich mir die Funktion halt selber geschreiben:

AMemo: Memo in dem gesucht wird
Search_Text:zu suchender Text
Direction: Suchrichtung (true=vorwärts,false=rückwärts)
Case_Sensitiv: Groß und Kleinschreibung beachten/missachten
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
function MemoFindText(AMemo:TMemo;Search_Text:string;Direction,Case_Sensitiv:bool):integer;
var sstart,slength,sendpos,i:integer;
    cut:string;
    c:char;
begin
sstart:=AMemo.SelStart;
slength:=AMemo.SelLength;
sendpos:=length(AMemo.lines.text);
if Case_sensitiv=false then ansilowercase(Search_Text);
//direction=true  - forward
//direction=false - backward
if direction=true then
   begin  //search forward
   for i:=sstart+slength to sendpos do
       begin
       c:=AMemo.lines.text[i];
       if Case_sensitiv=false then c:=ansilowercase(c)[1];
       if c=Search_Text[1then
          begin
          cut:=copy(AMemo.lines.text,i,length(Search_text));
          if Case_sensitiv=false then cut:=ansilowercase(cut);
          if cut=Search_text then
             begin
             result:=i-1;
             exit;
             end;
          end;
       end;
   end   //search forward
  else
   begin //search backward
   for i:=sstart-slength downto 0 do
       begin
       c:=AMemo.lines.text[i];
       if Case_sensitiv=false then c:=ansilowercase(c)[1];
       if c=Search_Text[1then
          begin
          cut:=copy(AMemo.lines.text,i,length(Search_text));
          if Case_sensitiv=false then cut:=ansilowercase(cut);
          if cut=Search_text then
             begin
             result:=i-1;
             exit;
             end;
          end;
       end
   end//search backward
  result:=-1;// string not found
end;


Die Funktion läuft ganz gut. Sie liefert die Anfangsposition des gesuchen Wortes wieder.

ABER bei großen Datei wird sie leider sehr langsam :?

Habt ihr irgendwelche Ideen wie man diese Funktion optimieren kann ?

_________________
GEIZ IST GEIL! - Ihr Sozialamt
Blackheart666
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2195

XP
D3Prof, D6Pers.
BeitragVerfasst: So 12.02.06 22:15 
Was spricht denn gegen RichEdit wenns ein aufgemotzter Editor sein soll.
starsurfer Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 334

Win 95, Win 98, Win XP, Win Vista, Linux
D5 Enterprise ,D2005, D6 Personal, Visual C++ Express 2005, C++ Builder 6 E, Dev-C++
BeitragVerfasst: So 12.02.06 22:31 
Ich hab nicht geplant das der Text formatiert werden kann. Er soll weder bunt noch kursiv, fett usw... dargestellt werden.

Und diese Formatierung is ja der große Unterschied zwischen Memo und Richedit...

(ok am Ende is das Ergebnis das Gleiche...also aus Prinzip:Memo :D )

_________________
GEIZ IST GEIL! - Ihr Sozialamt
Gausi
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8548
Erhaltene Danke: 477

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: Mo 13.02.06 10:26 
user profile iconstarsurfer hat folgendes geschrieben:
Habt ihr irgendwelche Ideen wie man diese Funktion optimieren kann ?

Wenn du wirklich nicht Pos etc. nehmen willst, dann musst du dir einen vernünftigen Stringsuch-Algorithmus schreiben. Beispiele dafür wären Suche in Wikipedia KNUTH-MORRIS-PRATT-ALGORITHMUS oder Suche in Wikipedia BOYER-MOORE-ALGORITHMUS. Die sind etwas komplizierter zu durchblicken, sind aber wesentlich schneller als dein (naiver) Algorithmus.

_________________
We are, we were and will not be.
starsurfer Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 334

Win 95, Win 98, Win XP, Win Vista, Linux
D5 Enterprise ,D2005, D6 Personal, Visual C++ Express 2005, C++ Builder 6 E, Dev-C++
BeitragVerfasst: Di 14.02.06 17:12 
thx gausi für dein Rat :)

ich hab meine Funktion jetzt ma auf
BOYER-MOORE-ALGORITHMUS umgestellt...

das is bei raus gekommen:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
function memofindtext(AMemo:TMemo;Search_Text:string;Direction,Case_Sensitiv:bool):integer;
var switch_list:array[32..255of integer;
    j,i,sstart,sendpos,searchpos,jumpvalve:integer;
    ordvalve:byte;
    cut:string;
begin
//start info
sstart:=AMemo.SelStart;
sendpos:=length(AMemo.lines.text);
//start info
if Case_sensitiv=false then Search_text:=ansilowercase(Search_Text);
//direction=true  - forward
//direction=false - backward
if Direction = True then
   begin //direction=true  - forward
   //Create switch_list forward
   for j:=32 to 255 do
       begin
       switch_list[j]:=length(Search_Text);
       for i:=length(Search_Text) downto 1 do
          begin
           if chr(j)=Search_Text[i] then
               begin
               switch_list[j]:=length(Search_Text)-i;
               break;
               end;
          end;
       end;
   //Create switch list forward
   searchpos:=sstart+1;
   jumpvalve:=0;
    repeat
    searchpos:=searchpos+jumpvalve;
    if Case_sensitiv=false then ordvalve:= ord(ansilowercase(AMemo.lines.text[searchpos+1])[1])
                           else ordvalve:= ord(AMemo.lines.text[searchpos+1]);
    if ordvalve<32 then jumpvalve:=length(Search_text)
                   else jumpvalve:=switch_list[ordvalve];
    if jumpvalve=0 then
       begin
       result:=searchpos-length(search_text)+1;
       cut:=copy(AMemo.lines.text,searchpos-length(Search_Text)+2,length(search_text));
       if case_sensitiv=false then cut:=ansilowercase(cut);
       if (searchpos-sstart>=length(Search_Text)) and
          (cut=Search_text)
          then exit else inc(searchpos);
       end;
    until (searchpos>=sendpos);
   end   //direction=true  - forward
  else
   begin //direction=false  - backward
   //Create switch_list backward
   for j:=32 to 255 do
       begin
       switch_list[j]:=length(Search_Text);
       for i:=1 to length(Search_Text) do
          begin
           if chr(j)=Search_Text[i] then
               begin
               switch_list[j]:=i-1;
               break;
               end;
          end;
       end;
   //Create switch_list backward
   searchpos:=sstart-1;
   jumpvalve:=0;
   repeat
    searchpos:=searchpos-jumpvalve;
    if Case_sensitiv=false then ordvalve:= ord(ansilowercase(AMemo.lines.text[searchpos+1])[1])
                           else ordvalve:= ord(AMemo.lines.text[searchpos+1]);
    if ordvalve<32 then jumpvalve:=length(Search_text)
                   else jumpvalve:=switch_list[ordvalve];
    if jumpvalve=0 then
       begin
       result:=searchpos;
       cut:=copy(AMemo.lines.text,searchpos+1,length(search_text));
       if case_sensitiv=false then cut:=ansilowercase(cut);
       if (sstart-searchpos>=length(Search_Text)) and
          (cut=search_text)
          then exit else dec(searchpos);
       end;
    until (searchpos<=0);
   end;  //direction=false  - backward
result:=-1//text not found
end;


er ist schon wesentlich schneller als mein "alter" algorithums...

Aber kann man den noch irgendwo optimieren?

_________________
GEIZ IST GEIL! - Ihr Sozialamt
Horst_H
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1654
Erhaltene Danke: 244

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: Di 14.02.06 17:30 
Hallo,

fuer die Vorwaertssuche ist es wohl einfacher so
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
function MemoFindText(AMemo:TMemo;Search_Text:string;Case_Sensitiv:bool):integer;
var 
sstart,slength:integer;
cut:string;
begin
sstart:=AMemo.SelStart;
slength:=AMemo.SelLength;
cut := copy(AMemo.lines.text,sStart,sLength);
IF Not(Case_Sensitiv) then
  begin
  cut := lowercase(cut);
  Search_Text := lowercase(Search_Text);
  end;
Result := Pos(Search_Text,cut);
If Result > 0 then
  Result := Pos +sStart;
end;


Gruss Horst