Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Recursivey searching (segments of) a sentence in a lexicon (python)

This program should return True if it is possible to generate the given sequence x from a given list of segments seglist. After finding one possible solution it should stop.

I tried replacing and repositioning the return commands, but there’s always a different problem coming up.

def valid_sequence(x, seglist): 
    if x in seglist:
        return True

    for i in seglist:
        if x.startswith(i):
            return valid_sequence(x[len(i):], seglist)
    return False

This returns the correct Boolean for sequence 'abc'and seglist ['a', 'ab', 'bc', 'c'], ['a', 'b', 'c'], and ['ab', 'bc'], but not for seglist ['a', 'ab', 'c'] because obviously it’s going through the 'a' variant but won’t be successfull and stops before going through 'ab', which it should.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I ran it through pythontutor and I understood some of the problems, but I could not determine how to fix them.

How do I write it so that it continues with segment 'ab' after taking the unsuccessful path of 'a'? Maybe I’m missing something else too, given that I can’t wrap my head around this recursion.

Is it even remotely possible this way, or do I have to take a totally different approach?

>Solution :

You were very close on this one. The main problem is that you should not return immediately in the recursive step. Notice that it will return False after the first loop that it is called. Consequently, the whole function will return False as well.

Said that, you should return only if the result is True:

def valid_sequence(x, seglist): 
    if x in seglist:
        return True

    for i in seglist:
        if x.startswith(i):
            if valid_sequence(x[len(i):], seglist):
                return True
    return False

This will fix the problem you mentioned, but there’s one more to go. If x = 'abc' and seglist = ['ab', 'b', 'c'] the function will correctly return True. But it will also return True for x = 'abbc', x = 'abbbc' and so on. This happens because the ‘b’ is being used indefinitly. I suppose that’s a not desired behavior. To overcome this we create a copy of the list for new calls and eliminate the used element:

import copy

def valid_sequence(x, seglist): 
    if x in seglist:
        return True

    for i in seglist:
        if x.startswith(i):
            newlist = copy.deepcopy(seglist)
            newlist.remove(i)
            
            if valid_sequence(x[len(i):], newlist):
                return True
    return False
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading