String Function find() - Find the location of the nth instance of a character in a string

Post your FreeBASIC source, examples, tips and tricks here. Please don’t post code without including an explanation.
Post Reply
dmontaine
Posts: 23
Joined: Mar 15, 2018 7:13

String Function find() - Find the location of the nth instance of a character in a string

Post by dmontaine »

Some additional modifications to the code of the previously uploaded count() function
and we can return the location of the nth instance of a character in a string.

Code: Select all

'Program: FindFunctionExample
' Find() finds the nth occurence of a character in a string 
' and returns the location

'==================================================
' find function
'==================================================

function find(byval SearchString as string,byval SearchChar as string,byval CharNum as integer) as integer
	if len(SearchString) = 0 or len(SearchChar) = 0 or CharNum = 0 then return 0
	
	dim CharCounter 	as integer
	dim sc 			as integer = asc(SearchChar)
	dim Ctr 			as integer
	dim FoundIt		as byte
	
	for Ctr = 0 to len(SearchString) - 1
		if SearchString[Ctr] = sc then CharCounter += 1 
		if CharCounter = CharNum then 
			Return Ctr + 1
			exit for
		end if
	next
	
	Return 0
end function

'==================================================
' Main Program
'==================================================
' Count the occurances of "|"

width 80,24
dim InputString	as string		= "|a|b|c|d|e|f|g|"
dim CharNum		as integer	= 13
dim Delimiter		as string		="|"
dim Location		as integer	= find(InputString,Delimiter,CharNum)

locate 1,1
print "find() function example program"
locate 3,5
print "The original string = " + InputString
locate 5,5
print "Occurrence " + str(CharNum) + " of """ + Delimiter + """"
locate 6,5

if Location = 0 then
	print("was not found!")
else
	print("was found at position " + str(Location))
end if
locate 8,1
print "Press any key to exit " ;
sleep

fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: String Function find() - Find the location of the nth instance of a character in a string

Post by fxm »

After 'Return Ctr + 1', 'exit for' is useless.

We can also use 'INSTR' to do the job:

Code: Select all

function find(byval SearchString as string,byval SearchChar as string,byval CharNum as integer) as integer
    if len(SearchString) = 0 or len(SearchChar) = 0 or CharNum = 0 then return 0
    dim CharCounter as integer = 0
    dim location as integer = 0
    do
        location = instr(location + 1,SearchString,SearchChar)
        if location = 0 then return 0
        CharCounter += 1
        if CharCounter = CharNum then return location
    loop
end function
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: String Function find() - Find the location of the nth instance of a character in a string

Post by dodicat »

Extending the string indexing method.
In the function tally, fill an array with all the positions of the string sought.
The sought string can be more than one character long.
Very fast because string indexing is used.

Code: Select all


Function tally(somestring As String,partstring As String,arr() As Long) As Long
      Dim As Long i,j,ln,lnp,count
      If Instr(somestring,partstring)=0 Then Return 0
      ln=Len(somestring)
      lnp=Len(partstring)
      Redim arr(1 To ln)'start with a big enough array to handle all circumstances
      count=0
      i=-1
      Do
            i+=1
            If somestring[i] <> partstring[0] Then Continue Do
            If somestring[i] = partstring[0] Then 'might be!
                  For j=0 To lnp-1 
                        If somestring[j+i]<>partstring[j] Then Continue Do 'not this time!
                  Next j
            End If
            ' if got here then a partstring has been found
            count+=1
            arr(count)=i+1 
            i=i+lnp-1
      Loop Until i>=ln-1 
      Redim Preserve arr(1 To count)'resize the output array
      Return count
End Function

Sub showabit(s As String,position As Long,delim As String) ' only to view some characters.
      Dim As String  g
      Locate Csrlin-1,50
      For n As Long=position-20 To position+20 +Len(delim)
            If n=position-1 Then Color 5
            If n=position+Len(delim)-1 Then Color 15
           if n<=len(s)-1 then Print Chr(s[n]);
      Next n
      Print
End Sub

#define range(f,l) Int(Rnd*(((l)+1)-(f))+(f))
#define char iif(rnd>.5,range(97,122),range(97,122)-32) 'any random ucase or lcase character

Dim As String s=String(10000000,0)
dim as double t
Randomize
Do
      t=timer
      Color 15
      For n As Long=0 To Len(s)-1
            s[n]=char
      Next
      Print "Start of string:"
      Print Mid(s,1,70)+ " . . . to ";Len(s)
      Print
      
      Dim As String LookFor=Chr(char,char,char,char)
      Print "Look for ";LookFor
      
      Redim As Long i()
      Var num=tally(s,LookFor,i())
      
      If num Then
            Print "position ","    found";Tab(59);"string near sought string"
            For n As Long=Lbound(i) To Ubound(i)
                  Print i(n);Tab(20);Mid(s,i(n),Len(LookFor)):showabit(s,i(n),LookFor)
            Next
            Print "tally = ";num
      Else
            Print "not found"
      End If
      Print
      print "Total time taken ";timer-t;"  seconds"
      Print "Press any key or Esc key"
      Sleep
      Loop Until Inkey=Chr(27) 
Post Reply