Avatar billede Slettet bruger
23. januar 2007 - 13:08 Der er 15 kommentarer

Loop problem

Hej. Jeg har et indput med sætningen "GULE ÆRTER MED FLÆSK", samt en variable med hele alfabetet (startende med mellemrum) gemt i OnCreate proceduren.

Det jeg vil, er at når man trykker på button3, vil den løbe ordet igennem i edit3 (standard: "GULE ÆRTER MED FLÆSK"), hvorefter den først vil finde hvor mellemrummene er, og skrive dem i hhv. key[1], key[2] og key[3], og så videre med alfabetet.

procedure TForm1.Button3Click(Sender: TObject);
var
  i,t: integer;
begin
for i:=1 to length(edit3.text) do
  begin
    for t:=1 to length(alfa) do
    begin
        if edit3.text[i] = alfa[t] then
        begin
          key[i]:=t;
        end;
    end;
label6.caption:=label6.caption +' '+ inttostr(key[i]);
  end;
   

problemet er bare, at der overhovedet ikke kommer noget fornuftigt  ud, ligenu står der i min label6:

8 22 13 6 1 28 ...


Lig mærke til 22! Hvordan i alverden kan den skrive 22? Starten skulle lyde noget á la: 5 11 15 14 4 9 ...
Avatar billede pidgeot Nybegynder
23. januar 2007 - 13:29 #1
Fordi du skriver udelukkende skriver hvert tegns position i alfa, startende fra en ende af. Sagt på en anden måde - du laver intet for at den skal finde mellemrummene først :)

Start din procedure med noget i stil med det her:

i:=Pos(' ',Edit3.Text);
while i<>0 do begin
  Label6.Caption:=Label6.Caption + ' ' + inttostr(i);
  i:=PosEx(' ',Edit3.Text,i+1);
end;

Så skulle den tage positionen på mellemrummene først, og derefter fortsætte som hidtil (jeg går ud fra det er det du vil have, er ikke helt sikker).

Vær dog liiige opmærksom på at jeg på stående fod ikke kan huske om man skal skrive det man vil søge efter før det man skal søge i, og om det er nødvendigt at bruge i+1 som tredje parameter til PosEx, eller om i er nok - jeg ville normalt se efter i dokumentationen, men det har jeg p.t. ikke mulighed for.
Avatar billede Slettet bruger
23. januar 2007 - 13:32 #2
PosEx? Den funktion kender jeg ikke, den brokker sig også når jeg kører programmet?
Avatar billede hrc Mester
23. januar 2007 - 13:37 #3
Nogle gange er I altså lidt hjælpeløse! Hvis du stiller markøren oveni PosEx og trykker <F1> så kommer der hjælpetekst frem der fortæller hvilken unit der skal inkluderes. Det virker sikkert også sådan i D7
Avatar billede pidgeot Nybegynder
23. januar 2007 - 15:31 #4
I dette tilfælde StrUtils - og i+1 lader til at være nødvendig, så vidt jeg kan se ud fra Borland's kildekode (source\win32\rtl\common\StrUtils.pas). (Og nu må jeg vist hellere prøve at få liv i Document Explorer igen, så jeg kan tilgå min dokumentation.)
Avatar billede hrc Mester
23. januar 2007 - 23:28 #5
Hvis du kan leve med at separatoren er et komma - har kigget i koden og den kan ikke ændres vha. StringList.Delimiter := #32; eller lignende - så vil nedenstående virke.

function TfrmMain.AnalyzeString(aInput: string): string;
const
  Alphabet = ' ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ';
var
  Ch : char;
  StringList : TStringList;
  i, j, InputLgd : integer;
begin
  StringList := TStringList.Create;
  try
    aInput := AnsiUpperCase(aInput); InputLgd := length(aInput);
    for i := 1 to length(Alphabet) do
    begin
      Ch := Alphabet[i];
      for j := 1 to InputLgd do
        if aInput[j] = Ch then
          StringList.Add(IntToStr(j));
    end;
    result := StringList.CommaText;
  finally
    StringList.Free;
  end;
end;
Avatar billede hrc Mester
23. januar 2007 - 23:31 #6
Man kan selvfølgelig erstatte kommaet bagefter:

for i := 1 to length(result) do
  if result[i] = ',' then
    result[i] := #32;

... men det smukke i algoritmen forsvinder.
Avatar billede kroning Nybegynder
24. januar 2007 - 00:38 #7
procedure TForm1.Button3Click(Sender: TObject);
var
  i,t,c: integer;
begin
    c:=1;
    for i:=1 to length(alfa) do
  begin
    for t:=1 to length(edit3.text) do
    begin
            if edit3.text[t] = alfa[i] then
            begin
          key[c]:=t;
        label6.caption:=label6.caption +' '+ inttostr(key[c]);
        inc(c);
      end;
    end;
    end;
end;
Avatar billede kroning Nybegynder
24. januar 2007 - 00:41 #8
Og det bliver lidt pænere at se på hvis man fjerne nogle begin-end:

procedure TForm1.Button3Click(Sender: TObject);
var
  i,t,c: integer;
begin
    c:=1;
    for i:=1 to length(alfa) do
    for t:=1 to length(edit3.text) do
            if edit3.text[t] = alfa[i] then
            begin
          key[c]:=t;
        label6.caption:=label6.caption +' '+ inttostr(key[c]);
        inc(c);
      end;
end;
Avatar billede kroning Nybegynder
24. januar 2007 - 00:56 #9
Her er en løsning hvor PosEx benyttes, den er faktisk 30% hurtigere end min forrige post:

procedure TForm1.Button3Click(Sender: TObject);
var
  i,t,x,c: integer;
begin
    c:=1;
    for i:=1 to length(alfa) do
  begin
      x:=1;
      t:=PosEx(alfa[i],edit3.Text,x);
    while t>0 do
    begin
        key[c]:=t;
      x:=t+1;
            label6.caption:=label6.caption +' '+ inttostr(key[c]);
            inc(c);
      t:=PosEx(alfa[i],edit3.Text,x);
    end;
    end;
end;
Avatar billede kroning Nybegynder
24. januar 2007 - 01:07 #10
Her er en løsning hvor Pos benyttes i stedet for PosEx og den løsning er lidt hurtigere end PosEx metoden, jeg kørte de 3 muligheder x antal gange og fik følgende:

1. Løsning, uden pos(ex): 10 sekunder
2. Løsning PosEx: 7 sekunder
3. Løsning Pos: 6.5 sekunder


procedure TForm1.Button3Click(Sender: TObject);
var
  i,t,c,x: integer;
  Temp : string;
begin
    c:=1;
    for i:=1 to length(alfa) do
  begin
    Temp:=edit3.Text;
    x:=0;
      t:=Pos(alfa[i],Temp);
    while t>0 do
    begin
        key[c]:=t+x;
            label6.caption:=label6.caption +' '+ inttostr(key[c]);
            inc(c);
      Delete(Temp,t,1);
      t:=Pos(alfa[i],temp);
      inc(x);
    end;
    end;
end;
Avatar billede kroning Nybegynder
24. januar 2007 - 01:29 #11
Jeg testede lige hrc´s løsning og den kørte x gange på under 1 sekund :) så en hel del hurtigere, jeg har nu rettet lidt på løsningen uden pos og løsningen med PosEx således at de er lige så hurtig som hrc´s løsning. PosEx løsningen er en lille smule hurtigere.

procedure TForm1.Button3Click(Sender: TObject);
var
  i,t,c: integer;
    tekst : string;
begin
    c:=1;
    tekst:=edit3.Text;
    for i:=1 to length(alfa) do
  begin
    for t:=1 to length(tekst) do
            if tekst[t] = alfa[i] then
            begin
          key[c]:=t;
        inc(c);
      end;
    end;
  tekst:='';
  for i:=1 to length(edit3.Text) do
        tekst:=tekst +' '+ inttostr(key[i]);

    label6.caption:=tekst;
end;

procedure TForm1.Button3Click(Sender: TObject);
var
  i,t,x,c: integer;
    tekst : string;
begin
    c:=1;
    tekst:=edit3.Text;
    for i:=1 to length(alfa) do
  begin
      x:=1;
      t:=PosEx(alfa[i],tekst,x);
    while t>0 do
    begin
        key[c]:=t;
      x:=t+1;
            inc(c);
      t:=PosEx(alfa[i],tekst,x);
    end;
    end;

  tekst:='';
  for i:=1 to length(edit3.Text) do
        tekst:=tekst +' '+ inttostr(key[i]);

    label6.caption:=tekst;
end;
Avatar billede hrc Mester
24. januar 2007 - 08:37 #12
Jeg giver 50 points til den der gør det i BASM :-)
Avatar billede Slettet bruger
24. januar 2007 - 14:04 #13
Haha, tak for hjælpen alle sammen, jeg har slet ikke så meget forstand på det så jeg røg af den meget gange, men tusinde tak for hjælpen!

Jeg kaster points efter kronning, simpelthen fordi at hans første svar passede mest til min oprindelige løsning :)
Avatar billede Slettet bruger
24. januar 2007 - 14:05 #14
På den anden side så skal jeg lige have et svar fra kronning :)?
Avatar billede kroning Nybegynder
24. januar 2007 - 15:11 #15
ok, hvis du deler dem ud er det fint med mig
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