Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Diese funktion schneller machen? (https://www.delphipraxis.net/32897-diese-funktion-schneller-machen.html)

Pseudemys Nelsoni 29. Okt 2004 11:42


Diese funktion schneller machen?
 
moin,

ich habe vor langer zeit mal folgende funktion geschrieben, die ich SEHR oft benutze (meistens zum parsen):

Delphi-Quellcode:
function GetTok(str: string; Tok: integer; sep: char): string;
var
  index: integer;
begin
  result := '';
  if (str = '') or (str = sep) or (Tok < 1) or (sep = '') then
    exit;
  if (pos(sep, str) = 0) and (Tok = 1) then
  begin
    result := str;
    exit;
  end;
  str := str + sep;
  while pos(sep+sep, str) > 0 do
    delete(str, pos(sep+sep, str), 1);
  if pos(sep, str) = 1 then
    delete(str, 1, 1);
  index := 1;
  while pos(sep, str) > 0 do
  begin
    if Tok = index then
    begin
      result := copy(str, 1, pos(sep, str)-1);
      exit;
    end
    else
    begin
      delete(str, 1, pos(sep, str));
      inc(index);
    end;
  end;
end;
ich rufe sie z.b so auf:

Delphi-Quellcode:
MeinString := 'Dies ist ein string';
s := GetTok(MeinString, 2, ' ');
das ergebnis wäre dann:

Zitat:

ist
nur sieht mir die funktion ziemlich lang aus und frage mich daher ob sie mein programm vielleicht langsam macht und es evtl eine schnellere variante gibt? (natürlich one stringlist...)

Matze 29. Okt 2004 11:45

Re: Diese funktion schneller machen?
 
Mittels der Unit StrUtils geht es auf jedenfall kürzer, ob der Code dann schneller ist, weiß ich nicht.

Du kannst dann nämlich Delphi-Referenz durchsuchenPosEx verwenden.

Edit: Welche Funktion hinter PosEx steckt, weiß ich allerdings auswendig nicht.

mirage228 29. Okt 2004 11:46

Re: Diese funktion schneller machen?
 
Hi,

einmal gibt es da das ExplodeExplode in der Code Library, dass einen String nach einem Seperator auflistet.

In deiner Funktion könntest Du noch das "const" vor dem String Parameter ergänzen.

mfG
mirage228

Pseudemys Nelsoni 29. Okt 2004 11:48

Re: Diese funktion schneller machen?
 
hallo matze,

wie bekomme ich denn mit posex() den teil den ich aus dem hauptstring möchte? wie ich sehe gibt posex einen integer und kein string zurück

hallo mirage, stimmt, const könnt ich noch dranhängen, danke

Matze 29. Okt 2004 11:52

Re: Diese funktion schneller machen?
 
Du bekommst den Index eines Strings, ab einer bestimmten Position und kann dir dann die 2 Indizes (in deinem Fall meistens Leerzeichen) merken und mittels Copy den String erhalten.

choose 29. Okt 2004 11:56

Re: Diese funktion schneller machen?
 
Dein Problem lässt sich allgemein, wenn ich es richtig erkenne, wie folgt beschreiben:
Code:
Gib genau den Teil eines Strings zurück, der durch bestimmte Kriterien eingegrenzt ist.
Um diese Grenzen gemäß Deiner Kriterien zu ermitteln, verwendest Du allerdings recht rechenintensive Stringoperationen wie "Konkatenation", "Löschen von Zeichen", ...

Versuche stattdessen die Kriterien zu überprüfen, ohne die Strings zu verändern (zB über die Zeichenpositionen innerhalb des Strings), so dass folgender Pseudo-Code schneller zum Ergebnis führt:
Delphi-Quellcode:
function CalcBoundInStringStartingAt(const AString: string;
  const AStart: Index; ...): Integer;
begin
  Result := AStart;
  while Result<Length(AString) and not DoesCriteriaMatch(...) do
    Inc(Result);
end;

function GetTok(const AString: string; ...): string;
var
  myLowerBound: Integer;
  myUpperBound: Integer;
begin
  myLowerBound := CalcBoundInStringStartingAt(AString, 1, ...);
  myUpperBound := CalcBoundInStringStartingAt(AString, Succ(myLowerBound), ...);
 
  UseBoundsToObtainResult(AString, myLowerBound, myUpperBound);
end;
Zu beachten sind selbstverstädnlich die Grenzfällen, bei denen die Kriterien nicht erfüllt sind, etc.

Stevie 29. Okt 2004 12:00

Re: Diese funktion schneller machen?
 
Hi,
Delphi-Quellcode:
function GetTok(str: string; Tok: integer; sep: char): string;
var
  i, j: integer;
  b: Boolean;
  pos: Integer;
begin
  Result := '';
  if (Sep = '') or (Tok < 1) then
    Exit;
  j := 1;
  b := False;
  pos := 0;
  for i := 1 to length(str) do
  begin
    if str[i] = sep then
    begin
      if not b then
      begin
        Inc(j);
        b := True;
      end;
      if j > Tok then
        Break
      else
        Continue;
    end
    else
      b := False;
    if (pos = 0) and (j = Tok) then
      pos := i;
  end;
  if Pos > 1 then
    Result := Copy(str, pos, i - pos);
end;
ist in jedem meiner Testfälle schneller als deine Funktion.

MfG
Stevie

P.S. Gibt's PosEx erst in Delphi7? Hab hier Delphi6Pro an der Arbeit und find das Teil nicht!?
Edit: Nochmal geändert...

negaH 29. Okt 2004 15:25

Re: Diese funktion schneller machen?
 
Delphi-Quellcode:
function ExtractToken(const Text: String; Index: Integer; const Seperator: Char = ' '): String;
var
  S,D: PChar;
begin
  S := PChar(Text);
  while (S^ <> #0) and (Index > 0) do
  begin
    if S^ = Separator then Dec(Index);
    Inc(S);

// falls mehrere Seperatoren nacheinander möglich sind, ohne Index zu ändern dann so
//
//    if S^ = Seperator then
//    begin
//      Dec(Index);
//      repeat
//        Inc(S);
//      until S^ <> Seperator;
//    end else Inc(S);
  end;
  D := S;
  while (D^ <> #0) and (D^ <> Separator) do
    Inc(D);
  SetString(Result, S, D - S);
end;
Gruß Hagen

Nothine 29. Okt 2004 22:13

Re: Diese funktion schneller machen?
 
Zitat:

Zitat von negaH
Delphi-Quellcode:
S := PChar(Text);

wäre
Delphi-Quellcode:
S := Pointer(Text);
nicht schneller? :gruebel:

negaH 29. Okt 2004 23:08

Re: Diese funktion schneller machen?
 
Warum sollte es ?

Gruß Hagen


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:41 Uhr.
Seite 1 von 3  1 23      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz