Avatar billede Slettet bruger
29. april 2001 - 18:29 Der er 8 kommentarer og
1 løsning

Flere af pos

Hejsa

Hvordan kan man finde ud af hvor mange gange denne string findes i en linie:
\"mikkel\"
??
Hvis man bruger pos, returnerer den kun den første den finder.

Mvh

Mikkel
Avatar billede borrisholt Novice
29. april 2001 - 18:56 #1
Hej Mikkel

HEr har du først et eksemple på hvordan man gør :

Placer et editfelt to memo felter samt en knap på en form :

I memo1 har du den tekst du vil søge i. Memo2 bliver brugt til at skrive resultatet i.


procedure TForm1.Button1Click(Sender: TObject);
var
  p : Pchar;
  count : Integer;
  Ps : Integer;
  szPattern : String;
begin
  szPattern := Edit1.Text;
  P:= @Memo1.Lines.Text[1];
  count := 0;
  Ps := 1;

  while bool(ps) do
  begin
    Ps := Pos(szPattern, p);
    if bool(ps) then
    begin
      inc(Count);
      inc(Integer(P), Ps);
    end;
  end;

  Memo2.Lines.Add(\'==============================\');
  Memo2.Lines.Add(\'Pascal-POS-search: \');
  Memo2.Lines.Add(\'==============================\');

  Memo2.Lines.Add(\'String Size: \' + IntToStr(Length(Memo1.Lines.Text)));
  Memo2.Lines.Add(\'Found: \' + IntToStr(Count));
end;


Koden virker ved at man ikke arbejder på en streng men der imod en Pchar, (pointer til en char), som du så giver din pos kommando ind.

Nå så du har fundet den første forkomst af det du søger efter flytter du blot din pointer, og så søger i resten indtil der ikke er mere at søger i. DVS din Pos kommando retuner 0 (nul). Så er vi færdige.

Det skrevende kode er ikke læsevenligt, men er skrevet for at være optimeret.

Der findes mange andere og hurtigere søge metoder end pos. Faktisk er pos kommandoen en af de langsomste. Har du bare en lille tekst er det lige meget, men har du et par hunderede sider har det STOR betyfning. Du kan fx nemt spare 10-12 sekunder ved at bruge en anden algoritme til at søge med.

Fx. kan jeg varmt anbefale Boyer-Moore-Horspool search algorithm. Men mere om det når du har 100% styr på pos, samt det skrevende kode ....

Jens B
Avatar billede borrisholt Novice
29. april 2001 - 19:01 #2
her har du lidt søge resultater at kigge på, fra forskellige algoritmer :

==============================
Turbo Search:
==============================
String Size: 128601
Found: 11592
ElapsedTime: Seconds: 0,00355268517292416
==============================
Boyer/Moore-search:
==============================
String Size: 128601
Found: 11592
ElapsedTime: Seconds: 0,011807083915111

==============================
Boyer-Moore-Horspool search algorithm:
==============================
String Size: 128601
Found: 11592
ElapsedTime: Seconds: 0,00399519939120771

==============================
Pascal-POS-search:
==============================
String Size: 128601
Found: 11592
ElapsedTime: Seconds: 10,8442098523109


Jens B
http://www.fotx.net/borrisholt
Avatar billede Slettet bruger
29. april 2001 - 19:39 #3
Jeg har lavet en smule om på scriptet. Nu virker det ikke, øv. Vil du lige give det et eftersyn?:

function FindAntal(Start, Slut, linie : String) : integer;
var
  p : Pchar;
  count : Integer;
  Ps : Integer;
begin
  start := lowercase(start);
  slut := lowercase(slut);
  linie := lowercase(linie);
  P:= @linie;
  count := 0;
  Ps := 1;
  while bool(ps) do
  begin
    Ps := Pos(start, p);
    if bool(ps) then
    begin
      inc(Count);
      inc(Integer(P), Ps);
    end;
  end;
result := Count;


P:= @linie;
count := 0;
Ps := 1;
while bool(ps) do
begin
  Ps := Pos(slut, p);
  if bool(ps) then
  begin
    inc(Count);
    inc(Integer(P), Ps);
  end;
  end;
Result := Result + Count;
end;

procedure TForm1.SpeedButton24Click(Sender: TObject);
var
  html : Integer;
  error : String;
begin
html := 0;

for i := 0 to SynEdit1.Lines.Count-1 do
begin
 
html := html + FindAntal(\'<html\', \'</html>\', SynEdit1.Lines[i]);

end;

if not(html mod 2 = 0) then
error := error + #13#10 + \'Der er ikke lige mange <html> og </html>.\';


showmessage(error);
end;

Error siger bare ikke noget.
Den kommer ikke med nogle fejl når jeg kører det??

Sådan ser SynEdit1.Lines ud:

<HTML></HTML>
<HEAD>
<TITLE> Ny side </TITLE>
</HEAD>
<BODY BGCOLOR=\"#000000\">


</BODY>
</HTML>


Den burde give en fejl i error.

/Mikkel
Avatar billede Slettet bruger
29. april 2001 - 19:40 #4
Woops, jeg kom til at svare på mit eget spørgsmål.
Avatar billede borrisholt Novice
29. april 2001 - 19:41 #5
du skal i hvertfald sætte

P:= pointer(Linie);

Det er nemlig IKKE det samme. Slet ikke !

Jens B
http://foxt.net/borrisholt
Avatar billede Slettet bruger
29. april 2001 - 19:48 #6
Det har du da heller ikke gjort med dit eksempel...
Avatar billede Slettet bruger
29. april 2001 - 19:49 #7
Sådan nu virker det!!!
Avatar billede borrisholt Novice
29. april 2001 - 19:50 #8
der har jeg tager adressen på det FØRSTE karekter :

P:= @Memo1.Lines.Text[1];


og ikke på Strengen :

P:= @Memo1.Lines.Text;

Jens B
http://foxt.net/borrisholt
Avatar billede Slettet bruger
29. april 2001 - 20:14 #9
Ahh, tak!
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester