Common Subsequence
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 43211 | Accepted: 17526 |
Description
A subsequence of a given sequence is the given sequence with some elements (possible none) left out. Given a sequence X = < x1, x2, ..., xm > another sequence Z = < z1, z2, ..., zk > is a subsequence of X if there exists a strictly increasing sequence < i1, i2, ..., ik > of indices of X such that for all j = 1,2,...,k, xij = zj. For example, Z = < a, b, f, c > is a subsequence of X = < a, b, c, f, b, c > with index sequence < 1, 2, 4, 6 >. Given two sequences X and Y the problem is to find the length of the maximum-length common subsequence of X and Y.
Input
The program input is from the std input. Each data set in the input contains two strings representing the given sequences. The sequences are separated by any number of white spaces. The input data are correct.
Output
For each set of data the program prints on the standard output the length of the maximum-length common subsequence from the beginning of a separate line.
Sample Input
abcfbc abfcab programming contest abcd mnp
Sample Output
4 2 0
Source
这个题是求最大公共子序列的长度,不是公共子串,他们的区别是::最长公共子串必须是连续的,而最长公共子序列不需要连续!
注意最长公共子串(Longest CommonSubstring)和最长公共子序列(LongestCommon Subsequence, LCS)的区别:子串(Substring)是串的一个连续的部分,子序列(Subsequence)则是从不改变序列的顺序,而从序列中去掉任意的元素而获得的新序列;更简略地说,前者(子串)的字符的位置必须连续,后者(子序列LCS)则不必。比如字符串acdfg同akdfc的最长公共子串为df,而他们的最长公共子序列是adf。
这个题就是个裸的cls
我简单说一下cls的原理
就是要让任意一个串每次增加一个字符分别和另一个串比较,求出最大的公共部分!
LCS(S1,S2)等于下列3项的最大者:
(1)LCS(S1,S2’)--如果C1不等于C2;
(2)LCS(S1’,S2)--如果C1不等于C2;
(3)LCS(S1’,S2’) LCS(S1‘,S2‘)+1--如果C1等于C2;
边界终止条件:如果S1和S2都是空串,则结果也是空串。
看张图好理解
先让A自己是一个串,和串BDCABA一个一个比
第一次比较 A和B他们都是一个串,末尾A和B不相等,最长的公共部分就是A前面串(空)和B或者B前面串(空)和A的最大一个,显然他们前面都没有,就是0
第二次比较A和 BD,末尾A和D不相等,最长的公共部分就是A前面串(空)和BD或者D前面串(B)和A的最大一个,显然他们公共部分为0
第三次比较A和BDC,末尾A和C不相等,最长的公共部分就是A前面串(空)和BDC或者C前面串(BD)和A的最大一个,显然他们公共部分为0
第四次比较A和BDCA,末尾A和A相等,最长的公共部分就是A前面串(空)和A前面串(BDC)公共长度加1(因为最后一个相等都是A)显然他们公共部分为1
....
依次写到末尾就是最长的公共部分的最大长度
套用模板:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 char s1[1000],s2[1000]; 6 int dp[1000][1000]; 7 int main() 8 { 9 int i,j; 10 while(scanf("%s%s",s1,s2)!=EOF) 11 { 12 memset(dp,0,sizeof(dp)); 13 int len1=strlen(s1); 14 int len2=strlen(s2); 15 for(i=1;i<=len1;i++)//i和j从1开始整体右下移一位,避开串钱为空的情况 16 { 17 for(j=1;j<=len2;j++) 18 { 19 if(s1[i-1]==s2[j-1]) 20 dp[i][j]=dp[i-1][j-1]+1; 21 else 22 dp[i][j]=max(dp[i][j-1],dp[i-1][j]); 23 } 24 } 25 printf("%d\n",dp[len1][len2]); 26 } 27 return 0; 28 }
这是个模板记住就行,欢迎各位留言询问!