I'm trying to remove substrings from a string using recursion in python

Question:

This is the code I got so far but it’s not working as intended and I’m not sure what’s making the problem.

def removeSubstrings(s, sub):
    if len(s) == 0:
        return ''
    if sub == s[0]:
        return removeSubstrings(s[1:], s)
    else:
        return s[0] + removeSubstrings(s[1:], sub)

This is the tester program:

from recursion import *
allPassed = True

def removeSubstringsMain():
    global allPassed
    
    testCases = [(1, 'abcdef', 'abc', 'def'),
                 (2, 'abcdef', 'def', 'abc'),
                 (3, 'abcdef', 'bcd', 'aef'),
                 (4, 'abcdef', '', 'abcdef'),
                 (5, 'abcdef', 'abcdef', ''), 
                 (6, 'aabbaabb', 'aa', 'bbbb'),
                 (7, 'abcdef', 'xyz', 'abcdef'),
                 (8, 'aabbaabb', 'a', 'bbbb')]
    
    for num, message, substring, expected in testCases:
        result = removeSubstrings(message, substring)
        if result != expected:
            print(f'Remove Substrings Test {num} Failed. Expected {expected} got {result}')
            allPassed = False

def main():
    removeSubstringsMain()
  #  closestMain()   ignore    
 #   strDistMain()   ignore
    if allPassed:
        print('All tests passed')

    
main()  

This is the error mesagess that’s coming from the tester:

Remove Substrings Test 1 Failed. Expected def got abcdef
Remove Substrings Test 2 Failed. Expected abc got abcdef
Remove Substrings Test 3 Failed. Expected aef got abcdef
Remove Substrings Test 5 Failed. Expected  got abcdef
Remove Substrings Test 6 Failed. Expected bbbb got aabbaabb
Remove Substrings Test 8 Failed. Expected bbbb got abbaabb
Asked By: Yusuf Halim

||

Answers:

if sub == s[0]:

tests if the first character is the substring. This will only work if the substring is only 1 character long.

You can use startswith() to test if the substring is at the beginning of s. Then you’ll need to slice off the entire substring when recursing.

You’ll need to treat an empty substring as a base case, since all strings start with an empty string, but removing it doesn’t change anything, so that will be an infinite loop.

def removeSubstrings(s, sub):
    if len(s) == 0:
        return ''
    if len(sub) == 0:
        return s
    if s.startswith(sub):
        return removeSubstrings(s[len(sub):], sub)
    else:
        return s[0] + removeSubstrings(s[1:], sub)
Answered By: Barmar

Instead of your function removeSubstrings, why not use the inbuilt string replace?

result = message.replace(substring, "")
Answered By: foo

Looks like someone already gave you a good answer. Here’s mine. Similar approach, but using slices larger than one character.

def removeSubstrings(s, sub) -> str:
    if len(s) == 0:
        return ''

    loc = s.find(sub)

    if loc == -1 or sub == '':
        return s

    return removeSubstrings(s[:loc], sub) + removeSubstrings(s[loc+len(sub):], sub)
Answered By: MorningSciFi
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.