Method: Dynamic Programming "Introduction to Arithmetic" P208
Optimal sub-structure + overlapping sub-problem
Set Xi,yi, number of previous I (prefix)
Set C[I,J] The length of the LCS for Xi,yi
C[I,J] = 0 (i ==0 | | j = 0)
C[I,J] = a[i-1,j-1] + 1 (i,j>0 &&xi=yi)
C[I,J] = max (C[i,j-1],c[i-1,j])
The length of the LCS (Xm-1, Y) and the length of the LCS (X, Yn-1) are not independent of each other: both require the length of the LCS (xm-1,yn-1).
"Structure of the longest common sub-sequence"
Set sequence x=<x1, X2, ..., xm> and y=<y1, Y2, ..., yn>, one of the longest common subsequence z=<z1, Z2, ..., zk>,
The
1. If Xm=yn, then Zk=xm=yn and Zk-1 are the longest common subsequence of Xm-1 and Yn-1;
2. If Xm≠yn and ZK≠XM, then Z is the longest common subsequence of Xm-1 and y;
3. If Xm≠yn and Zk≠yn, Z is the longest common sub-sequence of x and Yn-1.
By this recursive structure it is easy to see that the longest common subsequence problem has sub-problem overlapping properties.
Due to the fact that there are only a few sub-problems in Theta (M*n) in the sub-problem space, it is possible to improve the efficiency of the algorithm by using the dynamic programming algorithm to calculate the optimal value from the bottom up.
"Code Implementation"
Output two arrays of C[0..M, 0..N] and B[1..M, 1..N]. where C[I,J] Storage
The length of the longest common subsequence of Xi and YJ, B[i,j] records indicate the value of c[i,j] is achieved by the solution of which sub-problem,
This is used when constructing the longest common sub-sequence. Finally, the length of the longest common subsequence of X and Y is recorded in c[m,n]
In
"Similar workaround: Construct a Matrix"
Import Java.util.Random; public class lcs{ public static void Main (string[] args) { int substringLength1 = 20; int substringLength2 = 20; String x = getrandomstrings (substringLength1); String y = getrandomstrings (substringLength2); Long startTime = System.nanotime (); Int[][] opt = new Int[substringlength1 + 1][substringlength2 + 1]; for (int i = substringlength1-1;i>=0;i--) { for (int J =substring2-1;j>=0;j--) { if (X.charat (i) = Y.charat (j)) OPT[I][J] = opt[i+1][j+1] + 1; Else OPT[I][J] = Math.max (opt[i+1][j],opt[i][j+1]); } } System.out.println ("substring1:" +x); System.out.println ("Substring2:" +y); System.out.print ("LCS:"); int i = 0, j = 0; while (I < substringLength1 && J < substringLength2) { if (X.charat (i) = = Y.charat (j)) { System.out.print (X.charat (i)); i++; j + +; } else if (Opt[i + 1][j] >= opt[i][j + 1]) i++; Else j + +; } Long endTime = System.nanotime (); } } |
11th: The longest common subsequence (lcs:longest Common subsequence)