Longest common subsequence
Title description
Give you a sequence X and another sequence Z. When all elements in Z exist in X, and the order of subscripts in X is strictly increasing, then Z is called a subsequence of X.
For example: Z=<a,b,f,c> is a subsequence of sequence X=<a,b,c,f,b,c>, the subscript sequence of elements in Z in X is <1, 2,4,6>.
Now give you two sequences X and Y. What is the length of their longest common subsequence?
Input The
input contains multiple sets of test data. Each group of input occupies one line and is two strings separated by several spaces. The length of each string does not exceed 100.
Output
For each set of inputs, output the length of the longest common subsequence of two strings.
Sample input
abcfbc abfcab
programming contest
abcd mnp
Sample output
4
2
0
Subsequence: A subset of an original sequence related to the order of the original sequence
For example: a subsequence BSY of ABCSCY
A common subsequence is a subsequence shared by two sequences, for example, ABCSCY and ABFSGP have BSY sequences
So the longest common subsequence is the longest common subsequence of the strings at both ends
Problem solving
1. Violence law
This involves permutation and combination, which is exponentially related to the length of the string
2. Dynamic programming
2.1 Find the subsequence, consider the last bit of the two subsequences
Suppose A = a1, a2, a3, a4...ax B = b1, b2, b3,...by find the longest common subsequence Lcs(x,y)=Z=z1,z2...zm; the length of Z is calculated as lcs( x,y)
(1)ax = by
Assuming the last digit ax=by=t of Ax and By, then the last digit of Z Lcs(x,y)=zm=t
Proof: (by contradiction) The last digit of Lcs(x,y) is Aa=Bb is not t, and a<x,b<y, then t can be added to the back of the common subsequence to get a longer sequence, and Hypothesis contradiction
So zm=t
With zm=t, we can get lcs(x,y) = lcs(x-1,y-1)+1 when Ax = By
(2)Ax≠By
Here let the last digit of Lcs(x,y) be t
(2.1)t≠ax,有lcs(x,y)=lcs(x-1,y)
(2.2)t≠by,有lcs(x,y)=lcs(x,y-1)
Since both cases can happen, according to the definition of the longest common subsequence lcs(x,y)=max(lcs(x-1,y),lcs(x,y-1))
(3) When Ax or By is an empty sequence, lcs(x,y)=0
So we get the following recurrence relation
lcs(x,y) =
(1)lcsx-1,y-1)+1(ax=by=t)
(2)max(lcs(x-1,y),lcs(x,y-1))(t≠ax,t≠by)
(3) 0 Ax or By is empty
After finding the recurrence relation, there are two ideas: ①Using the recursion relation to recurse, from back to forward ②Using dynamic programming, from front to back, because there are too many overlaps in the recurrence relation For example: lcs(x-1,y) includes lcs(x-1,y-1). When solving, it will be solved multiple times, resulting in increased time complexity, so here we choose to use dynamic programming from front to back Push, store the solution of the sub-problem in an array for future use, thereby reducing time complexity
From the above recurrence relation, it is easy to think of using a two-dimensional array c[m][n] to store the result of the sub-problem
The following is the recursive expression of the array
From this two-dimensional array, the length of the longest common subsequence can be easily obtained, but how to get the longest functional common subsequence itself?
By going back to the two-dimensional array, taking the picture below as an example, we can easily see the solution process of the two-dimensional array
When ax=by=t occurs, it is the oblique arrow in the figure, and the character is printed at the position where the record occurs. When the array is traversed, the longest common subsequence is also printed.
#include<stdio.h>
#include<string.h>
int f(int a,int b)
{
if(a>=b)
return a;
else
return b;
}
int main()
{
char a[101],b[101];
int i,x,y,j,k,n,m,l;
while(scanf("%s%s",a,b)!=EOF)
{
int t=0;int d[101][101];
x=strlen(a),y=strlen(b);
for(i=0;i<x;i++)
for(j=0;j<y;j++)
d[i][j]=0;
for(i=1;i<=x;i++)
{
for(j=1;j<=y;j++)
{
if(a[i-1]==b[j-1])
d[i][j]=d[i-1][j-1]+1;
else
d[i][j]=f(d[i-1][j],d[i][j-1]);//这里可以用C++的max函数
}
}
/*for(i=1;i<=x;i++)
{
for(j=1;j<=y;j++)
printf("%d ",d[i][j]);
printf("\n");
}*/
printf("%d\n",d[x][y]);
}
return 0;
}