Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi pos von hinten (https://www.delphipraxis.net/105585-pos-von-hinten.html)

Luckie 3. Nov 2010 13:04

AW: pos von hinten
 
Warum das +2?

Mondengel 3. Nov 2010 13:04

AW: pos von hinten
 
Zitat:

Und warum +2?
Naja einmal weil ein String bei 1 anfängt und nicht bei 0 und
weil beim Anfangsbuchstaben des Substr die Position angegeben werden soll

-187- 3. Nov 2010 17:19

AW: pos von hinten
 
Hm ich habe mir den String immer umgedreht und dann ganz normal mit Pos gearbeitet... Die Länge des Strings - Die Reversed Position+1 ist das Ergebnis :D


Delphi-Quellcode:
function String_Reverse(S:String):String;
var
  i: Integer;
begin
  Result:='';
  for i:=Length(S) downto 1 do
    begin
      Result:=Result+Copy(S,i,1);
    end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  MyStr: String;
  MyPos: Integer;
begin
  MyStr:=String_Reverse(Edit1.Text);
  MyPos:=Pos('$',MyStr);
  ShowMessage('Die Position: '+IntToStr(Length(Edit1.Text)-MyPos+1));
end;
Naja wahrscheinlich hab ich mir das etwas zu kompliziert gestaltet :)

himitsu 3. Nov 2010 17:32

AW: pos von hinten
 
Zitat:

Delphi-Quellcode:
function String_Reverse(S:String):String;
var
  i: Integer;
begin
  Result:='';
  for i:=Length(S) downto 1 do
    begin
      Result:=Result+Copy(S,i,1);
    end;
end;

Also der Code ist ja extremst grausam und unperformat.
Delphi-Quellcode:
Copy(S,i,1) = S[i]
.
Und die Unmasse an String-Concationen ist sehr unperformant.

Delphi-Quellcode:
program Project5;

{$APPTYPE CONSOLE}

uses
  Windows, StrUtils;

function StringReverse_Copy(S: String): String;
var
  i: Integer;
begin
  Result := '';
  for i := Length(S) downto 1 do
    Result := Result + Copy(S, i, 1);
end;

function StringReverse_Char(S: String): String;
var
  i: Integer;
begin
  Result := '';
  for i := Length(S) downto 1 do
    Result := Result + S[i];
end;

function StringReverse_Direct(S: String): String;
var
  L, i: Integer;
begin
  L := Length(S);
  SetLength(Result, L);
  for i := L downto 1 do
    Result[i] := S[L - i + 2];
end;

var
  S, S2: String;
  C: Cardinal;
  i: Integer;

begin
  SetLength(S, 1234567);

  C := GetTickCount;
  for i := 0 to 9 do begin
    S2 := StringReverse_Copy(S);
    S2 := '';
  end;
  WriteLn(GetTickCount - C);

  C := GetTickCount;
  for i := 0 to 9 do begin
    S2 := StringReverse_Char(S);
    S2 := '';
  end;
  WriteLn(GetTickCount - C);

  C := GetTickCount;
  for i := 0 to 9 do begin
    S2 := StringReverse_Direct(S);
    S2 := '';
  end;
  WriteLn(GetTickCount - C);

  C := GetTickCount;
  for i := 0 to 9 do begin
    S2 := ReverseString(S);
    S2 := '';
  end;
  WriteLn(GetTickCount - C);

  ReadLn;
end.
Code:
2047
1296
110
47
Je länger der String, um so grausamer wird die nahezu expotentiell zur Zeichenanzahl steigene Rechenzeit.

-187- 3. Nov 2010 17:42

AW: pos von hinten
 
Ja offensichtlich nicht sehr performant :) Spielt aber auch keine große Rolle bei meinen Bastler Tools ;)

Mondengel 4. Nov 2010 08:57

AW: pos von hinten
 
Zitat:

Hm ich habe mir den String immer umgedreht und dann ganz normal mit Pos gearbeitet... Die Länge des Strings - Die Reversed Position+1 ist das Ergebnis
Funktioniert ja auch wenn es nur ein Zeichen ist, aber wenn ich mehrere Zeichen habe funktioniert der Code nicht mehr 8-)

Beispiel:
String: as9as9as0as9as9as0
Substring: as0

So nun drehst du den String und er sieht so aus
0sa9sa9sa9sa0sa9sa9sa9sa

So findet er nicht mehr as0

Darum drehe ich auch den Substring um :-D

himitsu 1. Jan 2011 21:02

AW: pos von hinten
 
Zitat:

Und warum +2?
Weil ich's grade nochmal sehe.

Die Strings sind ja 1-basierens (wie schon erwähnt)
Diese 2 sind nun zwei Mal die 1 (1+1=2, wenn man was wegkürzt) oder eher 4 Mal die 1 (1+1+1-1=2).

entweder
+1: einmal vom Pos, für die Umrechnung
+1: und das Length(SubString), um dort auf das letzte Zeichen umzurechen
Delphi-Quellcode:
Result := Length(S) - Length(SubStr) - Result + 2;
Result := Length(S) - (Length(SubStr) - 1) - (Result - 1);
also um den Index von a auf b zu verschieben
Code:
123456789
     678

987654321
 876
 a b
a = Ergebnis von Pos(...)
b = letztes Zeichen, welches nach dem Umdrehen dann das Erste ist.


oder
+1: Length(S) um den Startindex auf das letzte Zeichen zu verschieben (0-basierend)
+1: Pos(SubStr, S) auf 0-basierend umrechnen
+1: Length(SubStr) ebenfalls auf das letzte Zeichen umrechnen
-1: das Ergebnis auf 1-basierend umrechnen



so, und nun nochmal alles zusammen:

alle Delphi-Versionen (ab Delphi 2009 kein direktes ANSI verfügbar)
Delphi-Quellcode:
uses StrUtils;

function ReversePos(SubStr, S: String): Integer;
begin
  SubStr := AnsiReverseString(SubStr);
  S := AnsiReverseString(S);
  Result := Pos(SubStr, S);
  if 0 <> Result then Result := Length(S) - Length(SubStr) - Result + 2;
end;

function ReversePosEx(SubStr, S: String; Offset: Integer = 1): Integer;
begin
  SubStr := ReverseString(SubStr);
  S := ReverseString(S);
  Offset := Length(S) - Offset + 1;
  Result := PosEx(SubStr, S, Offset);
  if 0 <> Result then Result := Length(S) - Length(SubStr) - Result + 2;
end;
ab Delphi 2009
Delphi-Quellcode:
uses StrUtils, AnsiStrings;

function ReversePos(SubStr, S: String): Integer; overload;
function ReversePos(SubStr, S: AnsiString): Integer; overload;
function ReversePosEx(SubStr, S: String; Offset: Integer = 1): Integer; overload;
function ReversePosEx(SubStr, S: AnsiString; Offset: Integer = 1): Integer; overload;

implementation

function ReversePos(SubStr, S: String): Integer;
begin
  SubStr := ReverseString(SubStr);
  S := ReverseString(S);
  Result := Pos(SubStr, S);
  if 0 <> Result then Result := Length(S) - Length(SubStr) - Result + 2;
end;

function ReversePos(SubStr, S: AnsiString): Integer;
begin
  SubStr := AnsiReverseString(SubStr);
  S := AnsiReverseString(S);
  Result := Pos(SubStr, S);
  if 0 <> Result then Result := Length(S) - Length(SubStr) - Result + 2;
end;

function ReversePosEx(SubStr, S: String; Offset: Integer = 1): Integer;
begin
  SubStr := ReverseString(SubStr);
  S := ReverseString(S);
  Offset := Length(S) - Offset + 1;
  Result := PosEx(SubStr, S, Offset);
  if 0 <> Result then Result := Length(S) - Length(SubStr) - Result + 2;
end;

function ReversePosEx(SubStr, S: AnsiString; Offset: Integer = 1): Integer;
begin
  SubStr := AnsiReverseString(SubStr);
  S := AnsiReverseString(S);
  Offset := Length(S) - Offset + 1;
  Result := PosEx(SubStr, S, Offset);
  if 0 <> Result then Result := Length(S) - Length(SubStr) - Result + 2;
end;

Luckie 2. Jan 2011 08:37

AW: pos von hinten
 
Zitat:

Zitat von himitsu (Beitrag 1071689)
Zitat:

Und warum +2?
Weil ich's grade nochmal sehe.

Und genau deshalb wäre es sinnvoll daraus eine Konstante mit aussagekräftigen Bezeichner zu machen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:01 Uhr.
Seite 2 von 2     12   

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