Seite 5 von 5
Verfasst: 25.04.2007 23:06
von AND51
Phase?
Das wird aber eine Lange Phase. Von wo bis wo denn? PB 4.10 bis PB 99.99?
Da spiel ich lieber Phase 10...

Verfasst: 25.04.2007 23:23
von al90
AND51 hat geschrieben:Phase?
Das wird aber eine Lange Phase. Von wo bis wo denn? PB 4.10 bis PB 99.99?
Da spiel ich lieber Phase 10...

Ich meinte damit die Phase während Du den Befehl eintippst. Umso schneller
Du bist, desto weniger musste schwitzen.

Verfasst: 25.04.2007 23:29
von AND51
Ich mach mir nen Macro, das den Befehl umschreibt.
Aber halt, das geht ja gar nicht... Während ich an dem Wort hinter "Macro" vorbei muss, trifft mich garantiert der Kollaps!

Verfasst: 20.07.2007 21:08
von hjbremer
Hallo, viele gute Lösungen, einige schnell, andere langsam und fast alle schwer zu durchschauen, bis auf den von Edel. Habe den einmal in eine Prozedur gepackt und etwas verändert.
Denn er ist schnell, wenn der gesuchte String am Anfang steht. Naturgemäß langsam, wenn er erst am Ende auftaucht.
Dies kann man aber abstellen, so das der Code im Schnitt eine gute bis sehr gute Performance bringt. Auch wenn der gesuchte String sich erst im hinteren Teil befindet.
Code: Alles auswählen
quell$="Diese Prozedur sucht nicht von hinten, sondern fängt in der Mitte an. Deshalb ist diese Prozedur in vielen Fällen schneller als der Originalcode von Edel und auch schneller als die meisten hier vorgestellten Prozeduren."
such$ ="Edel"
Procedure.l FindLastString(heuhaufen.s, nadel.s, CaseSensitive=1)
Protected pos = 0
Protected lastpos=0
Protected start=Len(heuhaufen)/2 ; <-- im 1.Repeat ab Mitte suchen
If CaseSensitive = 0
heuhaufen = LCase(heuhaufen)
nadel = LCase(nadel)
EndIf
Repeat
lastpos = pos
pos = FindString(heuhaufen,nadel,start+pos+1)
start=0
Until pos = 0
If lastpos
ProcedureReturn lastpos
Else
pos = 0
lastpos=0
Repeat
lastpos = pos
pos = FindString(heuhaufen,nadel,start+pos+1)
Until pos = 0
EndIf
ProcedureReturn lastpos
EndProcedure
p=FindLastString(quell$, such$)
Debug p
Verfasst: 24.06.2009 07:49
von AND51
Meine von hinten suchende Prozedur etwas optimiert, weil ich sie gerade mal wieder brauchte.
Nutzt jetzt Bitshifting statt Divisionen und Multiplikationen.
Code: Alles auswählen
Procedure FindLastString(String$, StringToFind$, CaseInSensitive=0)
Protected length=Len(StringToFind$), *position=@String$+(Len(String$)-length)<<#PB_Compiler_Unicode
If StringToFind$
While *position >= @String$
If CompareMemoryString(*position, @StringToFind$, CaseInSensitive, length) = #PB_String_Equal
ProcedureReturn (*position-@String$)>>#PB_Compiler_Unicode+1
EndIf
*position-SizeOf(Character)
Wend
EndIf
EndProcedure
Debug FindLastString("berthold", "hold")
@ hjbremer
Deine ist nicht so gut, denn du weißt nie, wo der gesuchte String tatsächlich steht. Was, wenn er genau 1 Position links vor der Hälfte steht? Das wäre das schlechteste Szenario für deine Prozedur.
Verfasst: 24.06.2009 19:32
von hjbremer
für Minimalisten
Code: Alles auswählen
mem = StrRStrI_(@"Ich liebe PureBasic! Du auch?",0,@"liebe")
Parameters
pszSource
[in] Pointer to a null-terminated source string.
pszLast
[in] Pointer into the source string that defines the range of the search. Set pszLast to point to a character in the source string, and the search will stop with the preceding character. Set pszLast to NULL to search the entire source string.
pszSrch
[in] Pointer to the substring to search for.
Return Value
Returns the address of the last occurrence of the substring if successful, or NULL otherwise.
Verfasst: 08.08.2009 00:28
von .:M:.
Hier meine Protzidur
Code: Alles auswählen
Procedure FindLastString(String$, StringToFind$)
For i=1 To CountString(String$, StringToFind$)
temp$=StringField(String$, i, StringToFind$)
pos=pos+Len(temp$)+1
Next i
ProcedureReturn pos
EndProcedure
Debug FindLastString("anna", "a")
Verfasst: 08.08.2009 17:37
von schic
noch eine recht flotte Methode in ASM:
Code: Alles auswählen
Procedure.l inMemStrRev(StartPos, *Source, strStr.s)
; naiver Algorithmus überprüft ein gesuchtes Muster rückwärts
; an allen Positionen i eines Speicherbereichs beginnend bei
; StartPos, Ende der Suche bei *Source
result.l
PatLen = Len(strStr)
;init pointers etc.
MOV Ebx,strStr ; Ebx = Pointer to first Char in string
MOV Edx,*Source
MOV Ecx,Edx ; Ecx = Pointer to akt. Char in source
ADD Ecx,StartPos ; set source-pointer to startposition
SUB Ecx, PatLen
DEC Edx
;INC Ecx ; StartPos - 1
! rpt_SrcRev: ; startpoint for loop scanning through the source
MOV al,[Ecx]
DEC Ecx ; Ecx + 1
CMP Ecx,Edx ; if null (end of source-string)
JS endProcRev ; -> end Procedure, Result=0
CMP byte[Ebx],al ; if found first Char of strStr look for the rest
JNE rpt_SrcRev ; else go on with next Char in source
;found the first Char of strStr in source
;now look if the rest does match
Xor Edi,Edi ; Edi = 0, Edi = Pointer to akt. Char in strStr
! rpt_StrRev: ; startpoint for loop pounding the string
INC Edi ; Edi + 1 (the first Char in string is already found)
CMP byte[Ebx+Edi],0 ; if 0 (end of strStr)
JE got_itRev ; -> got it, all Chars of the string did match
MOV al,byte[Ecx+Edi+1] ; move actual Char in source to accumulator, have
; to add 1 cause Ecx already decreased before
CMP byte[Ebx+Edi],al ; if actual Char in source (Ebx+Edi) = act Char in string (al)
JE rpt_StrRev ; then take next Char
JMP rpt_SrcRev ; and go on with scanning source
! got_itRev:
;Result = Ecx - Source, to get the place in the source-string
SUB Ecx,Edx
INC Ecx
MOV result,Ecx
! endProcRev:
ProcedureReturn result
EndProcedure
; und zum testen
Macro FindReport()
PrintN ("pattern found at position: " + Str(a) + " in " + Str(timeGetTime_()-StartTime ) + " milliseconds")
PrintN (" ")
a=0
EndMacro
Text.s="axbbaaxbbaaxbbabbal axbbaaxbbaaxbbabbal axbbaaxbbaaxbbabbalaxbbaaxbbaaxbbabbal This is any Text of any number of characters With no content"
findstr.s= "many"
OpenConsole()
For i = 1 To 20;8
Text=Text+"|"+Text
Next
Text=findstr+Text
loopcount = 10;2;5000
PrintN ("starting to search " + Str(loopcount) + " times, in " + Str(Len(Text)) + " characters, for '" + findstr + "'")
PrintN (" ")
PrintN ("Search inMemStrRev")
lentxt=Len(Text)
lenfindstr=Len(findstr)
StartTime = timeGetTime_()
For i = 1 To loopcount
a=inMemStrRev(lentxt, @Text, findstr)
Next i
FindReport()
StartPos ist die Länge des Strings wenn alles durchsucht werden soll.