FindLastString() »»» Letztes Vorkommen von Strings ermitteln

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

FindLastString() »»» Letztes Vorkommen von Strings ermitteln

Beitrag von AND51 »

Hallo!

Möchte mal ne Competition starten, ein Gegenstück von FindString(), welches das erste Vorkommen eines Strings ermittelt. Ich will aber das letzte Vorkommen im String haben :)
Später folgt noch eine Prozedur, die das n. Vorkommen ermittelt (dazu am besten nen separatren Thread aufmachen!).

Ich fang mal an mit dem hier:

Code: Alles auswählen

Procedure FindLastString(String$, StringToFind$)
	Protected neu=FindString(String$, StringToFind$, 1), alt=neu
	While neu
		alt=neu
		neu=FindString(String$, StringToFind$, alt+1)
	Wend
	ProcedureReturn alt
EndProcedure


Debug FindLastString("anna", "a")
Es gelten die üblichen Mitmachregeln:
  • -Unicode+Threadsafe Support, wenn möglich
    -EnableExplicit Kompatiblität
    -Größte Bequemlichkeit für den Benutzer (optionale Parameter einbauen, etc.)
    -Möglichst gute Performance
Es gibt nix zu gewinnen, macht aber nichts, da sowieso Mitarbeiter und deren Angehörige von "Fantasiesoftware" nicht mitmachen dürfen. Der Rechtsweg ist ausgeschlossen.
Zuletzt geändert von AND51 am 23.04.2007 20:21, insgesamt 2-mal geändert.
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
Fluid Byte
Beiträge: 3110
Registriert: 27.09.2006 22:06
Wohnort: Berlin, Mitte

Beitrag von Fluid Byte »

Ist doch eigentlich Käse. Du must doch lediglich die Länge des Strings beim 'StartPosition' Paremeter angeben.
Windows 10 Pro, 64-Bit / Outtakes | Derek
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

Käse ist es, stimmt. Aber Recht hast du auch nicht.
Was soll ich denn mit der Länge des Strings beim 3. Parameter von FindString()?

Ich verbessere meine obige Version eben mal.
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
Fluid Byte
Beiträge: 3110
Registriert: 27.09.2006 22:06
Wohnort: Berlin, Mitte

Beitrag von Fluid Byte »

Ich dachte FindString() durchsucht immer den ganzen String unabhängig von der StartPosition. Insofern haste Recht. Ma' guckn' ob Ich was zusammenbastel. Bild
Windows 10 Pro, 64-Bit / Outtakes | Derek
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

> Ich dachte FindString() durchsucht immer den ganzen String unabhängig von der StartPosition.
Nein, da irrst du dich. StartPosition sagt, ab welcher Position er mit der Suche beginnen soll. Nützlich, wenn ich weiß, dass ein bestimtmes zeichen sowieso nur ab Position 32 oder so vorkommt oder ich das erste Ergebnis überspringen will.

Trotzdem hast du Recht, das brauchte ich hier nicht, bzw. hier bringt das nicht die Performance.

Bin auf deine Version gespannt! <)
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
bobobo
jaAdmin
Beiträge: 3873
Registriert: 13.09.2004 17:48
Kontaktdaten:

Beitrag von bobobo »

also

Code: Alles auswählen

haystack.s="Hier wird die Nadel drin gesucht. Also die Nadel im Heuhaufen."
needle.s="Nadel"


firstpos=FindString(haystack,needle,0)

lastpos=firstpos
Debug lastpos
While FindString(haystack,needle,lastpos+1)
lastpos =FindString(haystack,needle,lastpos+1)
Wend
Debug "letztes Vorkommen an Stelle "+Str(FindString(haystack,needle,lastpos))
‮pb aktuel 6.2 windoof aktuell und sowas von 10
Ich hab Tinnitus im Auge. Ich seh nur Pfeifen.
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Beitrag von edel »

Code: Alles auswählen

Repeat 
  lastpos = pos
  pos = FindString(haystack,needle,pos+1)
Until pos = 0
sollte auch reichen .
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

Das ist doch im Prinzip, dasselbe was ich gepostet habe.
Aber bei dir hat man's nicht als Befehl/Procedure. Und die optisch besseren Einrückungen fehlen. :|

//Edit: Ach edel du hast ja auch was gepostet! hab ich nicht gesehen, als ich gepostet habe...
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

Ich habe hier eine Prozedur, die von hinten gebinnt zu suchen. Desshalb müsste die performanter sein.

Sie vergleicht den 1. Buchstaben des StringToFind$ mit jedem Buchstaben von String$ von hitnen beginnend. Bei Treffer wird Buchstabe für Buchstabe der beiden Strings miteinander vergichen. Bei vollständiger Übereinstimmung gilt StringToFind$ als gefunden und das Ergebnis wird zurückgegeben.

Testergebnisse / Performance: Ich habe den ersten Code, der bisher euren Codes entspricht mit diesem verglichen. Außerdem habe ich noch den Code aus dem bisherigen Thread hier in einer FOR-Schleifen-Version.

Alle drei miteinander verglichen zeigt, dass der neue Code von mir hier der schnellste ist. Je länger die Strings, desto effektiver arbeitet dieser Algorithmus.

Code: Alles auswählen

Procedure.l FindLastString3(String$, StringToFind$)
	Protected n, i, l=StringByteLength(String$)-SizeOf(Character), l2=StringByteLength(StringToFind$)-SizeOf(Character)
	For n=l To 0 Step -SizeOf(Character)
		If PeekC(@String$+n) = PeekC(@StringToFind$)
			For i=0 To l2 Step SizeOf(Character)
				If PeekC(@String$+n+i) <> PeekC(@StringToFind$+i)
					Break
				EndIf
			Next
			If i = l2+SizeOf(Character)
				Break
			EndIf
		EndIf
	Next
	ProcedureReturn (n+SizeOf(Character))/SizeOf(Character)
EndProcedure


Debug FindLastString("Diese Prozedur sucht von hinten. Deshalb sollte diese Prozedur performanter sein als die bisherigen Prozeduren.", "Prozedur")
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
Thorium
Beiträge: 1722
Registriert: 12.06.2005 11:15
Wohnort: Germany
Kontaktdaten:

Beitrag von Thorium »

Vielen Dank für diese Idee! :allright:

Habe gerade mal versucht das ganze in Assembler umzusetzen. Hat leider net so funktioniert wie ich mir das dachte, gab nen IMA. Ich also mit OllyDebugger drann um zu schauen was vorsich geht. Und siehe da in OllyDbg lauft die .exe, ohne OllyDbg gibts eine IMA-Exception. Das is saugeil, weil man das verwenden kann um zu prüfen ob das Programm unter OllyDbg läuft.

Thx, thx, thx. :mrgreen:
Zu mir kommen behinderte Delphine um mit mir zu schwimmen.

Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke! Bild
Antworten