Seite 3 von 5
Verfasst: 23.04.2007 23:27
von al90
Ich hatte es mit einer Procedure und Memory-Befehlen versucht.
Weist schon, Peek + Poke und so. Brachte aber alles nix, hab den
Code auch nicht mehr.
Verfasst: 24.04.2007 11:28
von bobobo
AND51 hat geschrieben:Das ist doch im Prinzip, dasselbe was ich gepostet habe.
Aber bei dir hat man's nicht als Befehl/Procedure.
genau deshalb ist meins schneller
Und die optisch besseren Einrückungen fehlen.

Schönheit war nicht gefragt. Mein Code ist kürzer als Deiner
//Edit: Ach edel du hast ja auch was gepostet! hab ich nicht gesehen, als ich gepostet habe...
der von Edel geht nicht
Verfasst: 24.04.2007 13:00
von nco2k
fast doppelt so schnell wie die version von AND51:
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")
ps: habs jetzt nicht gross getestet, wer fehler findet darf sie behalten.
c ya,
nco2k
Verfasst: 24.04.2007 13:13
von AND51
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...

Verfasst: 24.04.2007 14:44
von ChristianK
Edel hat geschrieben:Code: Alles auswählen
Repeat
lastpos = pos
pos = FindString(haystack,needle,pos+1)
Until pos = 0
bobobo hat geschrieben: der von Edel geht nicht
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:
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")
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?

Verfasst: 24.04.2007 14:56
von AND51
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:
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

Verfasst: 24.04.2007 15:09
von ts-soft
>> 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

Verfasst: 24.04.2007 20:04
von bobobo
ChristianK hat geschrieben:
bobobo hat geschrieben: der von Edel geht nicht
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:
achso .. blind war
Das stand aber sehr nutzerunfreundlich nicht dabei.

Verfasst: 24.04.2007 21:22
von Xaby
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

Verfasst: 24.04.2007 21:30
von Thorium
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.

Man kann auch einfach von hinten suchen.
Das versuche ich gerade in inline-Assembler umzusetzen. Da ich da aber selber noch Anfänger bin, dauert das noch ein bissel.
