FindLastString() »»» Letztes Vorkommen von Strings ermitteln
genau deshalb ist meins schnellerAND51 hat geschrieben:Das ist doch im Prinzip, dasselbe was ich gepostet habe.
Aber bei dir hat man's nicht als Befehl/Procedure.

Schönheit war nicht gefragt. Mein Code ist kürzer als DeinerUnd die optisch besseren Einrückungen fehlen.

der von Edel geht nicht
//Edit: Ach edel du hast ja auch was gepostet! hab ich nicht gesehen, als ich gepostet habe...
pb aktuel 6.2 windoof aktuell und sowas von 10
Ich hab Tinnitus im Auge. Ich seh nur Pfeifen.
Ich hab Tinnitus im Auge. Ich seh nur Pfeifen.
fast doppelt so schnell wie die version von AND51:
ps: habs jetzt nicht gross getestet, wer fehler findet darf sie behalten.
c ya,
nco2k
Code: Alles auswählen
Procedure FindLastString(String.s, StringToFind.s, CaseSensitive=1)
If CaseSensitive = 0
String = LCase(String)
StringToFind = LCase(StringToFind)
EndIf
Protected StringLength = StringByteLength(String), StringToFindLength = StringByteLength(StringToFind), Offset = StringLength - StringToFindLength, CharacterLength = SizeOf(Character), Result
While Offset > -1
If CompareMemory(@String + Offset, @StringToFind, StringToFindLength)
Result = Offset / CharacterLength + 1
Break
EndIf
Offset - CharacterLength
Wend
ProcedureReturn Result
EndProcedure
Debug FindLastString("Diese Prozedur sucht von hinten. Deshalb sollte diese Prozedur performanter sein als die bisherigen Prozeduren.", "Prozedur")

c ya,
nco2k
~|__/
..o.o.. <--- This is Einkaufswagen. Copy Einkaufswagen into your signature to help him on his way to world domination.
..o.o.. <--- This is Einkaufswagen. Copy Einkaufswagen into your signature to help him on his way to world domination.
Ach DAS meint ihr mit CompareMemory()... Ich gebe zu, das ist gut! Da hätte ich auch drauf kommen müssen...
Danke nco2k !!!!
> Und die optisch besseren Einrückungen fehlen.
>> Schönheit war nicht gefragt.
>>> -Größte Bequemlichkeit für den Benutzer
Ist es nicht Bequemlichkeit, dem Benutzer einen besseren Überblick über den Code zu bieten, damit dieser ihn besser ansehen/bearbeiten kann? Sonst muss er ja alles manuell einrücken...
Danke nco2k !!!!

> Und die optisch besseren Einrückungen fehlen.
>> Schönheit war nicht gefragt.
>>> -Größte Bequemlichkeit für den Benutzer
Ist es nicht Bequemlichkeit, dem Benutzer einen besseren Überblick über den Code zu bieten, damit dieser ihn besser ansehen/bearbeiten kann? Sonst muss er ja alles manuell einrücken...

PB 4.30
Code: Alles auswählen
Macro Happy
;-)
EndMacro
Happy End
- ChristianK
- Beiträge: 77
- Registriert: 13.12.2004 14:55
Edel hat geschrieben:Code: Alles auswählen
Repeat lastpos = pos pos = FindString(haystack,needle,pos+1) Until pos = 0
Natürlich geht der Code von Edel, und sogar bestens! Das Ergebnis steht korrekt in 'lastpos'. Einfach ud simpel. gefällt mir! Beste Programmierkunst!:allright:bobobo hat geschrieben: der von Edel geht nicht
man kann alles bis zur unleserlichkeit (Geschwindigkeits-)optimieren. Aber bringts das? muss jede Zeile 5x lesen um den Sinn zu versthene. 21 Programmzeilen wo 4 genügen umd das Problem zu lösen?AND51 hat geschrieben:Code: Alles auswählen
Procedure.l FindLastString(String$, StringToFind$) Protected n, i, l=StringByteLength(String$)-SizeOf(Character), l2=StringByteLength(StringToFind$)-SizeOf(Character) Protected *String.Character, *StringToFind.Character For n=l To 0 Step -SizeOf(Character) *String=@String$+n *StringToFind=@StringToFind$ If *String\c = *StringToFind\c For i=0 To l2 Step SizeOf(Character) *String=@String$+n+i *StringToFind=@StringToFind$+i If *String\c <> *StringToFind\c Break EndIf Next If i = l2+SizeOf(Character) Break EndIf EndIf Next ProcedureReturn (n+SizeOf(Character))/SizeOf(Character) EndProcedure Debug FindLastString("Ich liebe PureBasic! Du auch?", "Ich")

Hallo!
Ich habe mal CopyMemoryString() benutzt. Hat eine eingebaute Case(In)Sensitive-Funktion, die sich um alles kümmert.
Außerdem ist meine Prozedur kürzer und ein paar ms schneller als die von co2k:
> Aber bringts das? muss jede Zeile 5x lesen um den Sinn zu versthene.
Dazu kann man den Code ja kommentieren. Ich habs aber nicht gemacht, weil ich ja weiß, wie der Code arbeitet.
Der von dir zitierte Code ist aber schon wieder alt, hab hier einen neueren, wo man den SInn auch mit 1x Lesen erfassen kann
Ich habe mal CopyMemoryString() benutzt. Hat eine eingebaute Case(In)Sensitive-Funktion, die sich um alles kümmert.
Außerdem ist meine Prozedur kürzer und ein paar ms schneller als die von co2k:
Code: Alles auswählen
Procedure.l FindLastString(String$, StringToFind$, CaseInSensitive=0)
Protected length=Len(StringToFind$), *position=@String$+(Len(String$)-length)*SizeOf(Character)
While @String$ < *position
If CompareMemoryString(*position, @StringToFind$, CaseInSensitive, length) = 0
ProcedureReturn (*position-@String$)/SizeOf(Character)+1
EndIf
*position-SizeOf(Character)
Wend
ProcedureReturn 0
EndProcedure
Debug FindLastString("Am Anfang sollte der Suchstring sollte stehen, um die Prozedur zu fordern!", "anfang", 1)
> Aber bringts das? muss jede Zeile 5x lesen um den Sinn zu versthene.
Dazu kann man den Code ja kommentieren. Ich habs aber nicht gemacht, weil ich ja weiß, wie der Code arbeitet.
Der von dir zitierte Code ist aber schon wieder alt, hab hier einen neueren, wo man den SInn auch mit 1x Lesen erfassen kann

PB 4.30
Code: Alles auswählen
Macro Happy
;-)
EndMacro
Happy End
- ts-soft
- Beiträge: 22292
- Registriert: 08.09.2004 00:57
- Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel - Wohnort: Berlin
>> man kann alles bis zur unleserlichkeit (Geschwindigkeits-)optimieren. Aber bringts das?
Nur wenn Geschwindigkeit erforderlich ist. Dann kann man aber durch
verzicht auf z.B. Peek, Poke, FindString, StringField usw. eine Menge ein-
sparen. Wenn ich z.B. einen Parser schreibe, sind diese Optimierungen
unverzichtbar. Wenn ich sowas nicht so oft benötige, mit kurzen Texten,
dann kann man sich die Umstände natürlich sparen, weil das bringts dann
nicht
Nur wenn Geschwindigkeit erforderlich ist. Dann kann man aber durch
verzicht auf z.B. Peek, Poke, FindString, StringField usw. eine Menge ein-
sparen. Wenn ich z.B. einen Parser schreibe, sind diese Optimierungen
unverzichtbar. Wenn ich sowas nicht so oft benötige, mit kurzen Texten,
dann kann man sich die Umstände natürlich sparen, weil das bringts dann
nicht

PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

achso .. blind warChristianK hat geschrieben:Natürlich geht der Code von Edel, und sogar bestens! Das Ergebnis steht korrekt in 'lastpos'. Einfach ud simpel. gefällt mir! Beste Programmierkunst!:allright:bobobo hat geschrieben: der von Edel geht nicht
Das stand aber sehr nutzerunfreundlich nicht dabei.

pb aktuel 6.2 windoof aktuell und sowas von 10
Ich hab Tinnitus im Auge. Ich seh nur Pfeifen.
Ich hab Tinnitus im Auge. Ich seh nur Pfeifen.
Was haltet ihr von der Idee:
Den String umdrehen, den SuchString umdrehen.
Dann FindString()
Dann braucht man nur noch von der Gesamtlänge des Strings die ermittelte Position abziehen und weiß, wo das letzte Vorkommen ist.
Nun braucht man sich nur noch um die schnellste Methode zu kümmern, die den String umdreht.
Aber schneller als der von Edel wird es wohl auch nicht sein.
Naja, wenn vergleichen lange dauert und viele SuchStrings drin sind, dann ist meine Idee vielleicht einen Tick angesagter.
Zu Edel: Ich denke, genauso ist es gedacht gewesen, deshalb kann man die Position gleich angeben und muss nicht immer erst Stückeln und von den Stücken dann die Position finden.
Edel zeigt, was man alles schaffen kann, wenn man zwei Minuten mal die Augen auf macht und eine Vision hat

Den String umdrehen, den SuchString umdrehen.
Dann FindString()
Dann braucht man nur noch von der Gesamtlänge des Strings die ermittelte Position abziehen und weiß, wo das letzte Vorkommen ist.
Nun braucht man sich nur noch um die schnellste Methode zu kümmern, die den String umdreht.
Aber schneller als der von Edel wird es wohl auch nicht sein.
Naja, wenn vergleichen lange dauert und viele SuchStrings drin sind, dann ist meine Idee vielleicht einen Tick angesagter.
Zu Edel: Ich denke, genauso ist es gedacht gewesen, deshalb kann man die Position gleich angeben und muss nicht immer erst Stückeln und von den Stücken dann die Position finden.
Edel zeigt, was man alles schaffen kann, wenn man zwei Minuten mal die Augen auf macht und eine Vision hat


Zuletzt geändert von Xaby am 24.04.2007 21:33, insgesamt 1-mal geändert.
Kinder an die Macht http://scratch.mit.edu/
Man kann auch einfach von hinten suchen.Xaby hat geschrieben:Was haltet ihr von der Idee:
Den String umdrehen, den SuchString umdrehen.
Dann FindString()
Dann braucht man nur noch von der Gesamtlänge des Strings die ermittelte Position abziehen und weiß, wo das letzte Vorkommen ist.
Nun braucht man sich nur noch um die schnellste Methode zu kümmern, die den String umdreht.
Das versuche ich gerade in inline-Assembler umzusetzen. Da ich da aber selber noch Anfänger bin, dauert das noch ein bissel.

Zu mir kommen behinderte Delphine um mit mir zu schwimmen.
Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke!
Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke!
