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!"
.