Joe Brandon
Joe Brandon

Reputation: 13

Tracing a recursive function for longest common substring

I am getting confused tracing the following recursive approach to find the longest common substring. The last two lines are where my confusion is. Specifically how is the count variable getting the answer when characters of both string matches? In the last line which "count" does this refer to i.e count in the function definition or the updated count from function call? Are there any resources for better understanding of recursions?

int recursive_substr(string a, string b, int m, int n,int count){
    if (m == -1 || n == -1) return count;
    if (a[m] == b[n]) {
        count = recursive_substr(a,b,m-1,n-1,++count);
    }
    return max(count,max(recursive_substr(a,b,m,n-1,0),recursive_substr(a,b,m-1,n,0)));
}

Upvotes: 1

Views: 175

Answers (1)

Stef
Stef

Reputation: 15504

The first thing to understand is what values to use for the parameters the very first time you call the function.

Consider the two following strings:

std::string a = "helloabc";
std::string b = "hello!abc";

To figure out the length of the longest common substring, you can call the function this way:

int length = recursive_substr(a, b, a.length()-1, b.length()-1, 0);

So, m begins as the index of the last character in a, and n begins as the index of the last character in b. count begins as 0.

During execution, m represents the index of the current character in a, n represents the index of the current character in b, and count represents the length of the current common substring.

Now imagine we're in the middle of the execution, with m=4 and n=5 and count=3. We're there:

a= "helloabc"
        ^m
b="hello!abc"    count=3
        ^n

We just saw the common substring "abc", which has length 3, and that is why count=3. Now, we notice that a[m] == 'o' != '!' == b[n]. So, we know that we can't extend the common substring "abc" into a longer common substring. We make a note that we have found a common substring of length 3, and we start looking for another common substring between "hello" and "hello!". Since 'o' and '!' are different, we know that we should exclude at least one of the two. But we don't know which one. So, we make two recursive calls:

count1 = recursive_substr(a,b,m,n-1,0); // length of longest common substring between "hello" and "hello"
count2 = recursive_substr(a,b,m-1,n,0); // length of longest common substring between "hell" and "hello!"

Then, we return the maximum of the three lengths we've collected:

  • the length count==3 of the previous common substring "abc" we had found;
  • the length count1==5 of the longest common substring between "hello" and "hello";
  • the length count2==4 of the longest common substring between "hell" and "hello!".

Upvotes: 1

Related Questions