Reputation: 323
I need to count the nunber of times the substring 'bob'
occurs in a string.
Example problem: Find the number of times 'bob' occurs in string s such that
"s = xyzbobxyzbobxyzbob" #(here there are three occurrences)
Here is my code:
s = "xyzbobxyzbobxyzbob"
numBobs = 0
while(s.find('bob') >= 0)
numBobs = numBobs + 1
print numBobs
Since the find function in Python is supposed to return -1 if a substring is unfound the while loop ought to end after printing out the incremented number of bobs each time it finds the substring.
However the program turns out to be an infinite loop when I run it.
Upvotes: 2
Views: 7406
Reputation: 1
def count_substring(string, sub_string):
count=a=0
while True:
a=string.find(sub_string)
string=string[a+1:]
if a>=0:
count=count+1;
else:
break
return count
Upvotes: 0
Reputation: 1
Here you have an easy function for the task:
def countBob(s):
number=0
while s.find('Bob')>0:
s=s.replace('Bob','',1)
number=number+1
return number
Then, you ask countBob whenever you need it:
countBob('This Bob runs faster than the other Bob dude!')
Upvotes: 0
Reputation: 1
Here is a solution that returns number of overlapping sub-strings without using Regex: (Note: the 'while' loop here is written presuming you are looking for a 3-character sub-string i.e. 'bob')
bobs = 0
start = 0
end = 3
while end <= len(s) + 1 and start < len(s)-2 :
if s.count('bob', start,end) == 1:
bobs += 1
start += 1
end += 1
print(bobs)
Upvotes: 0
Reputation: 88737
When you do s.find('bob')
you search from the beginning, so you end-up finding the same bob again and again, you need to change your search position to end of the bob you found.
string.find
takes start argument which you can pass to tell it from where to start searching, string.find
also return the position are which it found bob, so you can use that, add length of bob to it and pass it to next s.find
.
So at start of loop set start=0
as you want to search from start, inside loop if find
returns a non-negative number you should add length of search string to it to get new start:
srch = 'bob'
start = numBobs = 0 while start >= 0:
pos = s.find(srch, start)
if pos < 0:
break
numBobs += 1
start = pos + len(srch)
Here I am assuming that overlapped search string are not considered
Upvotes: 2
Reputation:
For this job, str.find
isn't very efficient. Instead, str.count
should be what you use:
>>> s = 'xyzbobxyzbobxyzbob'
>>> s.count('bob')
3
>>> s.count('xy')
3
>>> s.count('bobxyz')
2
>>>
Or, if you want to get overlapping occurrences, you can use Regex:
>>> from re import findall
>>> s = 'bobobob'
>>> len(findall('(?=bob)', s))
3
>>> s = "bobob"
>>> len(findall('(?=bob)', s))
2
>>>
Upvotes: 10
Reputation: 361565
find
doesn't remember where the previous match was and start from there, not unless you tell it to. You need to keep track of the match location and pass in the optional start
parameter. If you don't find
will just find the first bob
over and over.
find(...)
S.find(sub [,start [,end]]) -> int
Return the lowest index in S where substring sub is found,
such that sub is contained within s[start:end]. Optional
arguments start and end are interpreted as in slice notation.
Return -1 on failure.
Upvotes: 0