![]() |
pos von hinten
Hi,
ich möchte einen Substring in einem String suchen, und zwar von HINTEN. d.h: PosHinten('a', 'abcabc') => 4 und nicht 1 Gibt es so eine Funktion? |
Re: pos von hinten
geht doch ganz leicht:
Man nimmt die Länge und zieht davon die Position von vorne ab.
Delphi-Quellcode:
rollstuhlfahrer
str := 'aabbccddee';
Poshi := Length(str) - Pos('b', str); PS: Code nicht getestet, evt. +/- 1 noch hinzufügen |
Re: pos von hinten
ich meine nicht die Position von hinten gezählt, sonder die Position des ersten SubStr von hinten:
Delphi-Quellcode:
s := 'hallo ich heiße albert'
PosHinten('a', s) // => 15 und nicht 2 |
Re: pos von hinten
Delphi-Quellcode:
Quickedit: sorry es müsste "for i := Length(s) +1 downto Index do" heißen und nicht "for i := Length(s) downto Index do". Jetzt funktioniert es wieder.
function MyPosEx(const SubStr, s: string; Index: Integer = 1; Upwards: Boolean = False): Integer;
var i, intSubStrLen: Integer; begin Result := 0; if (Index < 1) then Exit; if Upwards then begin intSubStrLen := Length(SubStr); if (Index >= Length(s)) then Exit; if (intSubStrLen < 1) then Exit; for i := Index to Length(s) do begin if (Copy(s, I, intSubStrLen) = SubStr) then begin Result := I; Exit; end; end; end else begin intSubStrLen := Length(SubStr); if (intSubStrLen < 1) then Exit; for i := Length(s) +1 downto Index do begin if (I - intSubStrLen < 1) then Exit; if (Copy(s, I - intSubStrLen, intSubStrLen) = SubStr) then begin Result := I - intSubStrLen; Exit; end; end; end; end; procedure TForm1.FormCreate(Sender: TObject); const s = 'abcdefghijklmnopqrstuvwxyz'; c = 'bc'; begin ShowMessage(Format('MyPosEx of c: %d' + #13#10 + 'MyPosEx of c (down): %d' + #13#10 + 'Pos of c: %d', [ MyPosEx(c, s, 1, True), MyPosEx(c, s), Pos(c, s)])); end; |
Re: pos von hinten
Hier hat Amateurprofi eine wirklich verdammt schnelle Version geschrieben, die auch Rückwärts suchen kann.
Such mal ![]() |
AW: pos von hinten
Ist mir klar das das wahrscheinlich nicht mehr gebraucht wird :roll:,
schreib aber für alle die das gleiche Problem haben ^^. Hab einen kleinen aber schnellen Quellcode
Delphi-Quellcode:
kurz und funktioniert :)
uses StrUtils
function PosR(Substr, s : String) : Integer; var rStr : string; begin rStr := reverseString(s); result := Pos( reverseString(SubStr), reverseString(s)); if( 0 <> result) then begin result := length(S)-result-Length(SubStr)+2; end; end; Bye :cheer: |
AW: pos von hinten
Wozu ist rStr da, wenn es nicht benutzt wird? Sagt Dein Compiler nichts dazu?
|
AW: pos von hinten
Klein ist er, ja, aber schnell mit Sicherheit nicht. Hier wird ja erstmal der komplette String umgedreht und dann noch die Suche durchgeführt. Noch schlimmer: Er wird nicht nur umgedreht, sondern es wird ein 2. String erzeugt, der die Umkehrung des Originals beinhaltet.
Solange es keine performancekritische Stelle ist, kannst du den Code natürlich verwenden, aber ansonsten würde ich lieber auf die optimierte Funktion zurückgreifen. |
AW: pos von hinten
Und warum +2?
|
AW: pos von hinten
OOOOOOOOOps :shock:
danke für den Hinweis DeddyH ich war wohl etwas zu schnell :lol: Nartürlich brauch man rStr nicht :stupid:
Delphi-Quellcode:
Ist besser nicht 8-)
uses StrUtils
function PosR(Substr, s : String) : Integer; begin result := Pos(reverseString(SubStr), reverseString(s)); if( 0 <> result) then result := length(S) - result - Length(SubStr) + 2; end; @NameLozer Das hab ich nicht gewusst sorry :pale: sollt nur ein weiterer Vorschlag sein |
AW: pos von hinten
Warum das +2?
|
AW: pos von hinten
Zitat:
weil beim Anfangsbuchstaben des Substr die Position angegeben werden soll |
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:
Naja wahrscheinlich hab ich mir das etwas zu kompliziert gestaltet :)
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; |
AW: pos von hinten
Zitat:
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:
Je länger der String, um so grausamer wird die nahezu expotentiell zur Zeichenanzahl steigene Rechenzeit.
2047
1296 110 47 |
AW: pos von hinten
Ja offensichtlich nicht sehr performant :) Spielt aber auch keine große Rolle bei meinen Bastler Tools ;)
|
AW: pos von hinten
Zitat:
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 |
AW: pos von hinten
Zitat:
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:
also um den Index von a auf b zu verschieben
Result := Length(S) - Length(SubStr) - Result + 2;
Result := Length(S) - (Length(SubStr) - 1) - (Result - 1);
Code:
a = Ergebnis von Pos(...)
123456789
678 987654321 876 a b 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:
ab Delphi 2009
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;
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; |
AW: pos von hinten
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:06 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz