Entwickler-Ecke

Algorithmen, Optimierung und Assembler - Letzten Teilstring in String finden; Habe Problem!!


rstaeker - Mi 15.12.04 21:39
Titel: Letzten Teilstring in String finden; Habe Problem!!
Hallo,
ich möchte gerne das letzte Vorkommen eines Teilstrings in einem String finden. Ich brauche praktisch den Index des letzten Vorkommens des Teilstrings.

Mein bisheriger Code ( :!: erzeugt eine Endlosschleife)

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:
32:
function TText.ScanSource(const Source:String):boolean;
var
  Text, TempText:String;
  Position: integer;
  First,Last:integer;
  MaxLength: integer;
  Endfound:boolean;
begin
  Text:= Source;
  TempText:= Source;
  MaxLength:=Length(Text);
  Position:=0;
  Last:=0;
  EndFound:=False;

  First:=pos('&start',TempText);
  While ((Last<=MaxLength) or not EndFound) do
  begin
    TempText:=Copy(TempText,First, MaxLength);
    Position:=pos('&ende',TempText);
    if Position<>0 then
    begin
      Last:=Position;
      TempText:=Copy(TempText,First, MaxLength-Last-First);
    end else EndFound:=True;
  end;
{
  Aufruf einer Subfunktion zum Scan des Subtextes
  TempText:=Copy(Source,First, MaxLength-Last-First);
  ScanSub(TempText);
}

end;


Ich habe wahrscheinlich irgendwo einen Denkfehler drin, findet den Jemand?

Vielen Dank schonmal
Rene


patrick - Mi 15.12.04 23:09

ich habs nur überfolge aber:
wie wäre es denn wenn du das OR durch ein AND ersetzt? :D


rstaeker - Mi 15.12.04 23:14

Sch****

Vielen Dank Patrick!!

daß war es vielen Dank



Rene


baka0815 - Do 17.04.08 08:16

Gibt's denn da keine eingebaute Funktion?

Hab' die Methode LastDelimiter gefunden, aber die sagt mir ja nur die letzte Position eines der übergebenen Zeichen, bei einem Teilstring hilft das also leider gar nichts.

Bei .NET und Java gibt's für Strings die Methode lastIndexOf() - gibt's da für Delphi nichts vergleichbares? Muss man sich sowas wirklich selber schreiben?


Horst_H - Do 17.04.08 08:47

Hallo,

du kannst ja PosEx aus strutils nutzen oder _PosEx http://www.delphipraxis.net/topic61002_teilstring+in+anderem+string+suchenzaehlen.html&highlight=posex oder http://fastcode.sourceforge.net/fastcodeproject/41.htm kopieren.
Dann rufst PosEx solange auf bis es 0 wird, und davor war wohl das letzte Vorkommen.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
hellfreezes := false;
lastoccurence:= 0;
AbPos := 1;
repeat  
  AbPos := PosEx(Was,Worin,AbPos);
  If AbPos = 0 then 
     break;
  lastoccurence := AbPos
until hellfreezes;
..gefunden oder nicht gefunden


Gruß Horst
P.S.
temp war mal Abpos....


baka0815 - Do 17.04.08 08:54

Danke, wie's grundlegend funktioniert weiß ich ja. Gibt da hunderte Methoden - man könnte auch Original und Suchstring umdrehen und dann mit Pos arbeiten, die Länge des Strings dann minus das Ergebnis von Pos rechnen.

Oder einfach von hinten anfangen minus Anzahl Zeichen des Suchstrings und dann weiter nach vorne wandern, oder, oder, oder.

Aber 'ne built-in Variante gibt's wirklich nicht?


Gausi - Do 17.04.08 08:57

Eine eingebaute Variante gibts afaik nicht. Aber ne Scgleife mit break, die läuft, bis die Hölle zufriert, ist wohl etwas ungut ;-). Ich habs mal so gemacht

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
idx := pos(p,t);                  
moreidx := idx;
while (moreidx > 0and (moreidx < length(t)) do
begin
   idx := moreidx;
   moreidx := posEx(p,t,moreidx+1);                    
end;


Motzi - Sa 19.04.08 11:48

Doch, es gibt auch eine eingebaute Funktion die das kann, und die ist garantiert auch schneller als deine Version, denn wenn mich nicht alles täuscht verwendet sie das Boyer-Moore Verfahren. ;)
Es ist die Funktion SearchBuf aus der Unit StrUtils.


baka0815 - Mi 07.05.08 16:30

user profile iconMotzi hat folgendes geschrieben:
Doch, es gibt auch eine eingebaute Funktion die das kann, und die ist garantiert auch schneller als deine Version, denn wenn mich nicht alles täuscht verwendet sie das Boyer-Moore Verfahren. ;)
Es ist die Funktion SearchBuf aus der Unit StrUtils.


Ok, mit SearchBuf kann man einen Puffer vorwärts oder rückwärts durchsuchen, das ist ja schon mal etwas. Allerdings bekommt man ein PChar zurück, also einen Zeiger auf die Stelle, an der der Suchtext gefunden wurde.
Wie bekomme ich nun die Stelle selbst raus?

Ich suche "test" in "Dies ist ein Test und ein zweiter Test folgt", dann möchte ich als Ergebnis 35 haben.

Gibt's dafür was eingebautes, bzw. kann ich PChar so "umbiegen", dass ich die Position im String bekomme?


alzaimar - Mi 07.05.08 18:21


Delphi-Quelltext
1:
Index = Integer (ResultPtr) - integer (PointerAufErstesZeichen)