### The recursive LCS algorithm

• Developing of a recursive solution for LCS

• I will use 2 problems to illustrate the divide and conquer method for the LCS problem.

Note:

 The divide and conquer procedure is different for each type of problem.... Dynamic programming requires some creativity on the part of the programmer (i.e., you)

• Problem 1: find the longest common subsequence:

 ``` X = BAB length(X) = 3 Y = BBAB length(Y) = 4 ```

Graphically:

• 64,000 question:

 What smaller problem(s) can I use to solve this problem ???

• I see that the last characters are equal:

I can use this pair as a part of the longest common subsequence !

But I still need to find the rest of the common subsequence !!!

• This is the smaller LCS problem that can help me find my solution:

 ``` Find the LCS of: BA BBA ```

• Suppose I hire someone to solve this smaller LCS problem for me:

And he tells me that the solution = 2:

I can now solve my LCS problem as follows:

 ``` Use the solution LCS( BA, BBA ) = 2 characters as follows: I know the last character also matches, therefore: LCS( BAB, BBAB ) = 2 + 1 ```

• Problem 2: find the longest common subsequence:

 ``` X = BAC length(X) = 3 Y = ABCB length(Y) = 4 ```

Graphically:

• 64,000 question:

 What smaller problem(s) can I use to solve this problem ???

• I see that the last characters are different:

I cannot use last character in both strings as a part of the longest common subsequence !

Therefore:

 I can safely remove the last character from one of the strings

• These following smaller LCS problems can help me solve my (original) problem:

 ``` (1) Find the LCS of: BA (don't use last character) ABCB (2) Find the LCS of: BAC ABC (don't use last character) ```

• Suppose I know the solutions of these 2 smaller LCS problems --- for example, have someone else solve it for me:

I can now solve my LCS problem:

 ``` Use the solution LCS( BA, BBA ) = 2 characters as follows: I know the last character did not match, so : I can't use the last character in one of the strings in the common sequence. So: LCS( BAC, ABCB ) is equal to one of these: LCS( BAC, ABCB ) = LCS( BA, ABCB ) = 1 or: LCS( BAC, ABCB ) = LCS( BAC, ABC ) = 2 Since I am looking for the longest common subseuqnce, the solution of my problem is: LCS( BAC, ABCB ) = 2 ```

• Overview of the divide and conquer procedure:

Note:

 There are 4 LCS problems shown in the figure above The input of each of the LCS problem is gievn in the yellow boxes The character in the blue boxes that enclose some of the yellow boxes is the character that was removed from the original problem to obtain smaller problems in the divide step

• Notice that the original problem is divided up into smaller problems:

• Suppose we have obtained (just assume that we can do so !) the solutions of the smaller problems are:

 sol1 = LCS(n-1, m-1)          sol2 = LCS(n-1, m) sol3 = LCS(n, m-1)

• How to use the solutions sol1, sol2 and sol3 to solve the original problem is:

 ``` if ( xn == yn ) { Solution of original problem = sol1 + 1; } else { if ( sol2 >= sol3 ) { Solution of original problem = sol2; } else { Solution of original problem = sol3; } } ```

• The Base Case(s):

 ``` LCS(0, m) = 0, for all m = 0, 1, 2, ... LCS(n, 0) = 0, for all n = 0, 1, 2, ... ```

• Pseudo code:

 ``` int LCS( x, y ) { int sol1, sol2, sol3; /* -------------- Base case -------------- */ if ( x == "" OR y == "" ) { return(0); // LCS has 0 characters } /* --------------------------------------- Compare the last character in x and y --------------------------------------- */ n = x.length() - 1; m = y.length() - 1; if ( xn == ym ) { /* ------------------------------------- Solve smaller problem(s) ------------------------------------- */ sol1 = LCS( x - xn , y - ym ); /* ------------------------------------------- Use the solution of the smaller problem(s) to solve the ORIGINAL problem -------------------------------------------- */ return( sol1 + 1 ); } else // ( xn != ym ) { /* ------------------------------------- Solve smaller problem(s) ------------------------------------- */ sol2 = LCS( x - xn , y ); sol3 = LCS( x , y - ym); /* ------------------------------------------- Use the solution of the smaller problem(s) to solve the ORIGINAL problem -------------------------------------------- */ if ( sol2 ≥ sol3 ) return( sol2 ); else return( sol3 ); } ```

• The LCS Algorithm

• In Java:

 ``` /* ---------------------------------- Meaning of the input parameters x = x0 x1 x2 .... x(i-1) y = y0 y1 y2 .... y(j-1) ---------------------------------- */ int LCS( int i, int j, String x, String y ) { int sol1, sol2, sol3; /* ======================================== Base cases ======================================== */ if ( i == 0 || j == 0 ) { /* ------------------------------------------ One of the strings has 0 character => no match possible Longest common subsequence = 0 characters ------------------------------------------- */ return(0); } if ( x.charAt(i-1) == y.charAt(j-1) ) { sol1 = LCS(i-1, j-1, x, y); // Solve smaller problem return( sol1 + 1 ); // Use solution to solve orig. problem } else { sol2 = LCS(i-1, j, x, y); // Solve smaller problems sol3 = LCS(i, j-1, x, y); if ( sol2 >= sol3 ) // Use solution to solve orig. problems { return(sol2); } else { return(sol3); } } } ```

• Example Program: (Demo above code)