public static int solveLCS(String x, String y) { int i, j; /* =============================================== Initialize the base cases =============================================== for (j = 0; j < y.length()+1; j++) K[1][j] = 0; // x = "" ===> LCS = 0 for (i = 1; i < x.length()+1; i++) { /* ===================================================== Recycle phase: copy row K[1][...] to row K[0][...] ===================================================== */ for ( j = 0; j < y.length()+1; j++) K[0][j] = K[1][j]; K[1][0] = 0; for (j = 1; j < y.length()+1; j++) { if ( x.charAt(i-1) == y.charAt(j-1) ) { K[1][j] = K[0][j-1] + 1; } else { K[1][j] = max( K[0][j] , K[1][j-1] ); } } } // The value of LCS is in K[1][y.length()] return K[1][y.length()]; } |
only computes the length of the LCS
Example:
x = ABCABCABC (x.length() = 8) y = BABACBAB (y.length() = 7) solveLCS(x,y) will compute: L[8][7] = 6 |
(i.e.., it can tell you that the LCS is 6 characters long)
|
(i.e., the algorithm does not tell you that the LCS is ABABAB.)
The algorithm uses the LCS algorithm to perform the recursive step.
x = ABCABCABC y = BABACBAB |
A solution is:
(There are other LCS strings, e.g: ABABAB ( ABCABCABC and BABACBAB).
The algorithm that we study only find one solution, not all solution)
|
|
|
String findLCS_String( String x, String y ) { if ( base cases ) // We worry about base bases later !! { return (Base case solution); } else { Split string x in half: x1 = first half of x; x2 = second half of x; Find a correct split for string y: (we don't know how to do this yet) Let k = a correct split of string y; Split string y into: y1 = y[0..(k-1)]; y2 = y[k..n]; Solve smaller problems: Sol1 = findLCS_String( x1, y1 ); // LCS string of x1 and y1 Sol2 = findLCS_String( x2, y2 ); // LCS string of x2 and y2 Solve the original problem with Sol1 and Sol2: mySol = Sol1 + Sol2; return ( mySol ); } } |
|
|
|
Let's add this step to the algorithm (piece meal algorithm development)....
String findLCS_String( String x, String y ) { if ( base cases ) // We worry about base bases later !! { return (Base case solution); } else { Split string x in half: m = x.length(); mid = m/2; x1 = x.substring(0, mid); x2 = x.substring(mid, m); **************************************************************** Find a correct split for string y: n = y.length(); for ( k = 0; k < y.length(); k++ ) { y1 = y.substring(0, k); y2 = y.substring(k, n); if ( solveLCS(x1, y1) + solveLCS(x2,y2) == solveLCS(x,y) ) break; } **************************************************************** Split string y at the correct split: y1 = y.substring(0, k); y2 = y.substring(k, n); Solve smaller problems: Sol1 = findLCS_String( x1, y1 ); // LCS string of x1 and y1 Sol2 = findLCS_String( x2, y2 ); // LCS string of x2 and y2 Solve the original problem with Sol1 and Sol2: mySol = Sol1 + Sol2; return ( mySol ); } } |
|
Example:
"abcde" / \ "ab" "cde" / \ / \ "a" "b" "cd" "e" / \ "c" "d" |
|
String findLCS_String( String x, String y ) { if ( x.length() == 0 ) // Base case "" { return (""); // LCS = "" ******* } else if ( x.length() == 1 ) // Base case "?" { /* ================================= Find that character in y ================================= */ for ( int j = 0; j < y.length(); j++ ) if ( y.charAt(j) == x.charAt(0) ) return( x ); // Found: LCS = x **** return (""); // Not found: LCS = "" **** } else // Divide and conquer { Split string x in half: m = x.length(); mid = m/2; x1 = x.substring(0, mid); x2 = x.substring(mid, m); Find a correct split for string y: n = y.length(); for ( k = 0; k < y.length(); k++ ) { y1 = y.substring(0, k); y2 = y.substring(k, n); if ( solveLCS(x1, y1) + solveLCS(x2,y2) == solveLCS(x,y) ) break; } Split string y at the correct split: n = y.length(); y1 = y.substring(0, k); y2 = y.substring(k, n); Solve smaller problems: Sol1 = findLCS_String( x1, y1 ); // LCS string of x1 and y1 Sol2 = findLCS_String( x2, y2 ); // LCS string of x2 and y2 Solve the original problem with Sol1 and Sol2: mySol = Sol1 + Sol2; return ( mySol ); } } |
public static String findLCS_String(String x, String y) { int mid, i, j; int m, n; String C = ""; m = x.length(); // m = length of x n = y.length(); // n = length of y /* ===================================================== Base case 1: "" ===================================================== */ if ( m == 0 ) { return ""; // LCS = "" } /* ===================================================== Base case 2: x = "?" ===================================================== */ if ( m == 1 ) { /* ===================================== The input x consists of 1 character Find the single common character in y ===================================== */ for ( i = 0; i < n; i++ ) if ( y.charAt(i) == x.charAt(0) ) return( x ); // Found: LCS = x return ""; // Not found: LCS = "" } /* ===================================================== General case: x has 2 or more characters ===================================================== */ String x1="", x2=""; // x1 = first half of x, x2 = second half int c1=0, c2=0; // c1 = length of first LCS, c2 = second int c = solveLCS( x, y ) ; // This is the sum of the correct split x1 = x.substring( 0, m/2 ); // First half of x x2 = x.substring( m/2, m ); // Second half of x /* -------------------------------------------------- Find a correct split of y -------------------------------------------------- */ for ( k = 0; k < n; k++ ) { c1 = solveLCS( x1, y.substring(0, k) ) ; // LCS of first half c2 = solveLCS( x2, y.substring(k, n) ) ; // LCS of second half if ( c1 + c2 == c ) break; // Found a correct split of y !!! } /* -------------------------------------------------- Here: k = a correct split location of y .... Solve smaller problems -------------------------------------------------- */ String y1 = y.substring( 0, k ); String y2 = y.substring( k, n ); String sol1 = findLCS_String( x1, y1 ); String sol2 = findLCS_String( x2, y2 ); /* ------------------------------------------------------------ Use solution of smaller problems to solve original problem ------------------------------------------------------------ */ return ( sol1 + sol2 ); } |
How to run the program:
|
Sample output:
x = abcabcabc y = babacbab LCS_String(abcabcabc,babacbab) LCS_String(abca,ba) LCS_String(ab,b) LCS_String(a,) LCS_String(b,b) LCS_String(ca,a) LCS_String(c,) LCS_String(a,a) LCS_String(bcabc,bacbab) LCS_String(bc,bac) LCS_String(b,b) LCS_String(c,ac) LCS_String(abc,bab) LCS_String(a,ba) LCS_String(bc,b) LCS_String(b,b) LCS_String(c,) LCS = babcab |