Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Nextchar Algo zu langsam


xtZ - So 22.07.07 21:19
Titel: Nextchar Algo zu langsam
Hallo,
Ich hoffe ich bin hier richtig.

Ich habe gerade eben folgenden Algo geschrieben:
Er soll immer die nächste Zeichenkette liefern.
z.b.:
nextchar('abc','a') = b
nextchar('abc','c') = aa
nextchar('abc','ab') = ac
usw...


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
function nextchar(scharset:string;sword:string):string;
var
  slastchar:string;
begin
  slastchar := sword[length(sword)];

  if stringofchar(scharset[length(scharset)],length(sword)) = sword then begin
    result := stringofchar(scharset[1],length(sword)+1)
  end
  else begin
    if slastchar = scharset[length(scharset)] then begin
      result := nextchar(scharset,copy(sword,1,length(sword)-1))+scharset[1]
    end
    else begin
      slastchar := copy(scharset,pos(slastchar,scharset)+1,1);
      result := copy(sword,1,length(sword)-1)+slastchar
    end;
  end;
end;


Er funktioniert soweit auch ganz gut, aber er ist mir zu langsam, wenn er oft wiederholt wird. :gruebel:
Bsp.:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
var
  s:string;
  f:textfile;
begin
  AssignFile(f, 'C:\test.txt');
  ReWrite(f);

  s:='a';

  repeat
    writeln(f,s);
    s:=nextchar('abcdefghijklmnopqrstuvwxyz',s);
  until s = 'zzzzz';

  closefile(f);


Hat vll jemand ein paar Ideen, wie man ihn optimieren kann, damit er schneller läuft?
Gibt es vll einen schnelleren Ersatz für die "copy" oder "stringofchar" Funktion etc.?


Danke :)


arj - So 22.07.07 21:25

Könntest Du mit Deinen eigenen Worten nochmal erklären was genau das Ding überhaupt tun soll?

Irgendwie blick ichs nicht. :(


xtZ - So 22.07.07 21:43

user profile iconarj hat folgendes geschrieben:
Könntest Du mit Deinen eigenen Worten nochmal erklären was genau das Ding überhaupt tun soll?

Irgendwie blick ichs nicht. :(


Es soll aus einem Charset alle möglichen Kombinationen generieren, also so eine Art: http://de.wikipedia.org/wiki/Brute-Force-Methode


BenBE - So 22.07.07 22:59

Nicht getestet, aber versuch's doch mal so:

Wenn ich mich nicht vertan hab, sollte es so gehen:

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:
function NextChar(Charset: String; Current: String): String;
var
    I: Integer;
    T1: array[char] of Byte;
    T2: array[Byte] of char;
begin
    //Setup some stuff ... Could be outsourced ...
    For I := 0 to 255 do
    Begin
        T1[Chr(I)] := 0;
        T2[I] := #0;
    end;
    for I := 1 To Length(Charset) do
    Begin
        T1[Charset[I]] := I;
        T2[I] := Charset[I];
    end;

    //Perform the magic ...
    I := Length(Current);
    Repeat
        Current[I] := T2[1 + (T1[Current[I]] mod Length(Charset))];
        Dec(I);
    Until (I<1OR (T1[Current[I+1]] <> 1);

    If (I<1AND (T1[Current[I+1]] <> 1Then
    Begin
        Current := T2[1] + Current;
    end;
    Result := Current;
end;


Ungetestet, sollte aber funzen ... Wie in der Routine angedeutet, erhält man noch etwas Speed, wenn man die beiden Arrays T1 und T2 vorinitialisiert irgendwoher übergibt.


xtZ - So 22.07.07 23:08

Danke, aber funktioniert leider nicht.
Der Aufruf NextChar('abc','b') muss "c" zurückliefern, aber er liefert "ac" zurück.
Der Aufruf NextChar('abc','c') muss "aa" zurückliefern, aber er liefert "a" zurück.


arj - So 22.07.07 23:13

Gehts dir eigentlich drum, alle Permutationen des Strings zu bekommen?
Oder genau das Verhalten was du beschrieben hast?


Bernhard Geyer - So 22.07.07 23:29

Und hier die gleiche Frage bei Delphi-Praxis (http://www.delphipraxis.net/topic114793_nextchar+algo+zu+langsam.html)


BenBE - So 22.07.07 23:41

Hatte noch nen kleinen Bug drin:


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:
function NextChar(Charset: String; Current: String): String;
var
    I: Integer;
    T1: array[char] of Byte;
    T2: array[Byte] of char;
begin
    //Setup some stuff ... Could be outsourced ...
    For I := 0 to 255 do
    Begin
        T1[Chr(I)] := 0;
        T2[I] := #0;
    end;
    for I := 1 To Length(Charset) do
    Begin
        T1[Charset[I]] := I;
        T2[I] := Charset[I];
    end;

    //Perform the magic ...
    I := Length(Current);
    Repeat
        Current[I] := T2[1 + (T1[Current[I]] mod Length(Charset))];
        Dec(I);
    Until (I<1OR (T1[Current[I+1]] <> 1);

    If (I<1AND (T1[Current[I+1]] = 1Then
    Begin
        Current := T2[1] + Current;
    end;
    Result := Current;
end;


Jetzt sollte es gehen ...