So ich hab auch noch bischen rumprobiert
AppendStringIfUnique = 422 ms
AddTok = 578 ms
AddIt2(von mir) 219 ms
AddIt3(von mir) 266 ms
[Edit]
Fehler in Funktion wurde behoben und Zeiten korrigiert
AddIt2 entfernt überflüssige Trennzeischen nicht
AddIt3 entfernt überflüssige Trennzeischen
[/Edit]
Allerdings weiß ich nicht ganz ob unter irgendwelchen Umständen meine Funktion fehlerhaft zurückgibt, wäre also nicht schlecht wenn mal jemand bischen testen könnte.
Delphi-Quellcode:
function AddIt2(const S, T: string; const C: Char; CS: Boolean = False): String;
function IsSame(Str1: PChar; Str2: PChar; ALen: Integer): Boolean;
var LPos: Integer;
begin
result := True;
LPos := 0;
while result and (LPos < ALen) do
begin
if Str1^ <> Str2^ then
result := False;
inc(Str1);
inc(Str2);
inc(LPos);
end;
end;
var LPos1, LPos2, LSourceLen, LTLen: Integer;
LFound: Boolean;
LS, LT: String;
LSP, LTP: PString;
begin
LSourceLen := Length(S);
if Length(S) = 0 then
result := T
else begin
if CS then
begin
LSP := @S;
LTP := @T;
end else begin
LS := AnsiLowerCase(S);
LT := AnsiLowerCase(T);
LSP := @LS;
LTP := @LT;
end;
LFound := False;
LTLen := Length(T);
LPos1 := 1;
LPos2 := 1;
while (LPos2 <= LSourceLen) and not(LFound) do
begin
if (LSP^[LPos2] = C) then
begin
LFound := (LPos2 - LPos1 = LTLen) and IsSame(@LSP^[LPos1], PChar(LTP^), LPos2 - LPos1);
LPos1 := LPos2 + 1;
end else if (LPos2 = LSourceLen) then
begin
LFound := (LPos2 - LPos1 + 1 = LTLen) and IsSame(@LSP^[LPos1], PChar(LTP^), LPos2 - LPos1 + 1);
LPos1 := LPos2 + 1;
end;
inc(LPos2);
end;
if LFound then
result := S
else
begin
if S[LSourceLen] = C then
result := S + T
else
result := S + C + T;
end;
end;
end;
Delphi-Quellcode:
function AddIt3(
const S, T:
string;
const C: Char; CS: Boolean = False):
String;
function IsSame(Str1: PChar; Str2: PChar; ALen: Integer): Boolean;
var LPos: Integer;
begin
result := True;
LPos := 0;
while result
and (LPos < ALen)
do
begin
if Str1^ <> Str2^
then
result := False;
inc(Str1);
inc(Str2);
inc(LPos);
end;
end;
var LPos1, LPos2, LSourceLen, LTLen: Integer;
LFound: Boolean;
LS, LT:
String;
LSP, LTP: PString;
begin
LSourceLen := Length(S);
if LSourceLen = 0
then
result := T
else begin
if CS
then
begin
LSP := @S;
LTP := @T;
end else begin
LS := AnsiLowerCase(S);
LT := AnsiLowerCase(T);
LSP := @LS;
LTP := @LT;
end;
LFound := False;
LTLen := Length(T);
LPos1 := 1;
LPos2 := 1;
while (LPos2 <= LSourceLen)
and not(LFound)
do
begin
if (LSP^[LPos2] = C)
then
begin
LFound := (LPos2 - LPos1 = LTLen)
and IsSame(@LSP^[LPos1], PChar(LTP^), LPos2 - LPos1);
LPos1 := LPos2 + 1;
end else if (LPos2 = LSourceLen)
then
begin
LFound := (LPos2 - LPos1 + 1 = LTLen)
and IsSame(@LSP^[LPos1], PChar(LTP^), LPos2 - LPos1 + 1);
LPos1 := LPos2 + 1;
end;
inc(LPos2);
end;
if LFound
then
result := S
else
begin
if S[LSourceLen] = C
then
result := S + T
else
result := S + C + T;
end;
//überflissige Zeischen rauskicken
LPos2 := 1;
LSourceLen := Length(result);
for LPos1 := 1
to LSourceLen
do
begin
if (result[LPos1] <> C)
or (LPos1 <= 1)
or (result[LPos1 - 1] <> C)
then
begin
result[LPos2] := result[LPos1];
inc(LPos2);
end;
end;
if result[LPos2 - 1] = C
then
dec(LPos2);
SetLength(result, LPos2 - 1);
end;
end;
@Dani: Die Funktion ist um den Faktor 10 Schneller? Ich kann mir nicht vorstellen das So große unterschiede auftreten das deine Funktion gleich 10 mal schneller ist. Außerdem hast du bei dieser Variante das Casesensitive vergessen. Wenn ich bei mir als Parameter das Casesensitive auf False setze komme ich dann auch nur noch auf 78 ms
@Pseudemys Nelsoni: Bist du dir sicher das du die Trennzeischen herausfiltern willst wenn ein Leerstring dazwischen ist? Schließlich ist ein Leerstring nicht unbedingt etwas ungültiges.