0

Ok so here's my problem, I defined a function that's suppose to count the number of times a certain fragment occurs in a string. The function starts searching at Index[0] and subsequent searches start at the index of the last match in the string.

HERE'S THE CODE

def function(fragment, string):
    count = -1
    last_match = 0
    while last_match != -1:
        count += 1
        last_match = string.find(fragment, last_match)
    return count

Now here's the problem, When pass the parameters to the function with a fragment that's obviously a match in the string I get an infinite loop. When I fix the infinite loop, If a pass fragment that located in Index[0] the function doesn't return a the right count???

ex:
function('gtg' , 'gttacgtggatg' ) This gives me an infinite loop

function('gtt' , 'gttacgtggatg' ) This doesn't return a count..

Just looking for some help and input..

Thanks

4 Answers 4

4

You should use existing functionality, if possible:

"aabbccaabb".count("aa")

The count method does exactly what you want. The above example returns 2.

Sign up to request clarification or add additional context in comments.

Comments

1

You have two mistakes:

  1. String documentation states that find will return -1 if the fragment is not found
  2. The last_match returns the index of the beginning of the match and so if you search again from that index you will find the same match again and again.

So you would probably have to use this :

def function(fragment, string):
    count = -1
    last_match = 0
    while last_match != -1:
        count += 1
        last_match = string.find(fragment, last_match)
        if last_match != -1:
            last_match += 1
    return count

>>> function('gtt' , 'gttacgtggatg' )
1
>>> function('gtg' , 'gttacgtggatg' )
1

Of course you could also rely on string.count(fragment) if you're not interested in overlapping matches... or regular expressions as mentionned by previous answers...

>>> 'gttacgtggatg'.count('ctt')
0
>>> 'gttacgtggatg'.count('gtt')
1

Comments

0

Have you considered using regular expressions? It's well adapted to your use. Python re module

Update: To expand off that, if you do something like this...

import re

...

def countOccurrences(myFragment, myString): expr = re.compile(myFragment) return len(expr.findall(myString))

2 Comments

No not really, I think there's a solution to the problem without using RE's.. I'm just to tired to think about it.. ;-) Maybe I'll give it a break and get back to it 2mm with a fresh mind.
I think Achim's count method is right on the ball. I'll leave my post here for the sake of archiving.
0

Logically, your problem is that you're simply finding the same match over and over again:

last_match = string.find(fragment, last_match)

...will start from where you found the last match, which will simply give you the same position back! You need to use string.find(fragment, last_match + 1), which will require you to jump through hoops to use a sentinel for your initial value of last_match.

Achim's answer answer is spot on: you should use existing functionality to do this.

1 Comment

Your absolutely right Detly, That's why I said when I fix the infinite loop it's all fine and dandy until the fragment passed as parameter begins in Index[0] in the string..

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.