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? :lol:

Da spiel ich lieber Phase 10... :wink:

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? :lol:

Da spiel ich lieber Phase 10... :wink:
Ich meinte damit die Phase während Du den Befehl eintippst. Umso schneller
Du bist, desto weniger musste schwitzen. :lol:

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! :lol:

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 :mrgreen:

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 :D

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.