VB Replace function

Post your FreeBASIC source, examples, tips and tricks here. Please don’t post code without including an explanation.
TJF
Posts: 3809
Joined: Dec 06, 2009 22:27
Location: N47°, E15°
Contact:

Post by TJF »

vbmrupp wrote:In your Sub the passed source string is changed, therefore you would have to have a copy in the callee before passing it. Unless you want the source string altered. So a copy is required somewhere on the stack.
Altering the source string is exactly what I have in mind, when I use a replace sub (function) -- nothing else.
xroot
Posts: 32
Joined: Aug 30, 2010 18:35

Replace In Asm

Post by xroot »

Here is a fast "Replace" substitute in Asm.
Try it out and see if it's fast.

Code: Select all


Dim shared as zstring ptr dStr=CAllocate(500)

Function Replace(iStr As zstring ptr,iFind As zstring ptr,iRep as zstring ptr) As zstring ptr
    Dim as integer iSize=Len(*iStr)-Len(*iFind)
        Asm
        mov esi,[iStr]
        add [iSize],esi
        mov ebx,[iFind]
        inc dword ptr[iSize]
        mov edi,[dStr]
        sub esi,1
        jmp Start1
Start2: add esi,ecx
Start1: add esi,1
        cmp [iSize],esi
        jle Done
        movzx eax,BYTE PTR[esi]
        cmp al,[ebx]
        je Match
        mov [edi],al
        add edi,1
        jmp Start1
Match:  mov ecx,-1
        mov edx,ebx
B1:     add ecx,1
        movzx eax,BYTE PTR[edx]
        test eax,eax
        jz Change
        add edx,1
        cmp [esi+ecx],al
        je B1
        movzx eax,BYTE PTR[esi]
        mov [edi],al
        add edi,1
        jmp Start1
Change: mov edx,[iRep]
        sub ecx,1
B2:     movzx eax,BYTE PTR[edx]
        test eax,eax
        jz Start2
        add edx,1
        mov [edi],al
        add edi,1
        jmp B2
Done:   mov ecx,-1
B3:     add ecx,1
        movzx eax,BYTE PTR[esi+ecx]
        mov [edi+ecx],al
        test eax,eax
        jnz B3
        mov eax,[dStr]
        mov [Function],eax
    End Asm
End Function

Dim as zstring ptr S=@"Mississippi",F=@"i",R=@""

?*Replace(S,F,R)
Deallocate dStr
sleep
Last edited by xroot on Nov 27, 2010 15:42, edited 1 time in total.
Sisophon2001
Posts: 1706
Joined: May 27, 2005 6:34
Location: Cambodia, Thailand, Lao, Ireland etc.
Contact:

Re: Replace In Asm

Post by Sisophon2001 »

xroot wrote: <snip>

Code: Select all

Function Replace(iStr As zstring ptr,iFind As zstring ptr,iRep as zstring ptr) As zstring ptr
    Dim as integer iSize=Len(*iStr)-Len(*iFind)
    Dim as zstring ptr dStr=CAllocate(Len(*iStr)*2)
Hi xroot,

I think you need to deallocate dStr or you will get a memory leak.

Garvan
Makoto WATANABE
Posts: 231
Joined: Apr 10, 2010 11:41
Location: Japan
Contact:

Re: VB Replace function

Post by Makoto WATANABE »

Dear All;

I tried
"by xroot » Nov 26, 2010 20:34, Last edited by xroot on Nov 27, 2010 15:42"
with
"FreeBASIC Compiler - Version 1.09.0 (2021-12-31), built for win32 (32bit)".

However, the following error was displayed.
error 11: Expected constant in 'Dim shared as zstring ptr dStr=CAllocate(500)'

Please teach me how to fix it.
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: VB Replace function

Post by fxm »


Dim shared as zstring ptr dStr=CAllocate(500)
Dim shared as zstring ptr dStr
dStr=CAllocate(500)
' .....
' .....
' end of program
DeAllocate(dStr)
Makoto WATANABE
Posts: 231
Joined: Apr 10, 2010 11:41
Location: Japan
Contact:

Re: VB Replace function

Post by Makoto WATANABE »

Dear fxm;

Thanks for your prompt help.
I was able to replace Japanese ASCII strings.
I am very grateful to you.
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: VB Replace function

Post by dodicat »

Ten years since xroot!, but very fast code.
This code is slightly slower, but no asm and is OK for 32 and 64 bits.
(gives the same answer as xroot, I did CAllocate(500000000) to be safe)
How does it do with Japanese ASCII strings I wonder?
fb 1.09.0, win 10.

Code: Select all

#cmdline "-gen gcc -O 2"
Function tallynum(somestring As String,partstring As String) As Integer
  Dim As Integer i,j,ln,lnp,count,num
  ln=Len(somestring):If ln=0 Then Return 0
  lnp=Len(partstring):If lnp=0 Then Return 0
  count=0
  i=-1
  Do
    i+=1
    If somestring[i] <> partstring[0] Then Continue Do
    If somestring[i] = partstring[0] Then
      For j=0 To lnp-1
        If somestring[j+i]<>partstring[j] Then Continue Do
      Next j
    End If
    count+=1
    i=i+lnp-1
  Loop Until i>=ln-1
  Return count
End Function

Function SAR(original As String ,find As String ,replace As String) As String
  If Len(find) = 0 Then Return original
  Var t=tallynum(original,find) 'find occurencies of find
  If t=0 Then Return original
  Dim As Long found,n,staid,m
  Var Lf = Len(find),Lr = Len(replace),Lo = Len(original)
  t = Len(original) - t * Lf + t * Lr             'length of output string
  Dim As String res = String(t,0)                 'output string
  Do
    If original[n] = find[0] Then               'got a possible
      For m = 0 To Lf - 1
        If original[n + m] <> find[m] Then Goto lbl 'no
      Next m
      found = 1                               'Bingo
    End If
    If found Then
      For m = 0 To Lr - 1
        res[staid] = replace[m]             'insert the replacerment
        staid += 1
      Next m
      n += Lf
      found = 0
      Continue Do
    End If
    lbl:
    res[staid] = original[n]
    staid += 1
    n += 1
  Loop Until n >= Lo
  Return res
End Function

print sar("Mississippi","i","")
print
dim as string s
dim as string g="11001111000001"
for n as long=1 to 25
    g+=g
next
print "Length original "; len(g)

dim as double t=timer
s=sar(g,"11110000","z")
print "Time taken in seconds ";timer-t
print "Length final    ";len(s)
print
print left(s,50)
print ". . ."
print right(s,50)
sleep

 
Makoto WATANABE
Posts: 231
Joined: Apr 10, 2010 11:41
Location: Japan
Contact:

Re: VB Replace function

Post by Makoto WATANABE »

Dear dodicat;

Using your function, I was able to perform fast Japanese string replacement in both ShiftJIS ASCII and UNICODE (WString).
Thank you for always teaching me.
Post Reply