最长公共子序列问题( Longest Common Subsequence problem,LCS) 是求两个给定序列X= {x1,x2, ... ,xn}与Y= {y1,y2,...,yn} 最长公共子序列的问题。
如果序列z同时为X和y的子序列,那么Z就称为X与Y的公共子序列。举个例子,设X= {a,b,c,b,d,a,b}、Y= {b,d,c,a,b,a},那么序列{b,.c,a} 就是X与Y的公共子序列。但是,序列{b,c,a} 并不是x与Y的最长公共子序列。因为这个序列的长度为3,而X与y之间还存在长度为4 的公共子序列{b,c,b,a}。由于没有长度大于等于5 的公共子序列,所以{b,c,b,a} 就是x与y的最长公共子序列之一。
请编写一个程序,对给定的两个字符串x、Y输出最长公共子序列z 的长度。给定字符串仅由英文字母构成。
输入 给定多组数据。第1行输入数组组数q。接下来的2 x q 行输人数据组,每组数据包含X、Y共2个字符串,每个字符串占1行。
输出 输出每组X、Y的最长公共子序列Z的长度,每个长度占1行。
限制 1<q<150
1<x、y的长度< 1000
若某组数据中X或Y的长度超过100,则q不超过20。
最长公共子序列
代码:
int lcs(String str1, String str2) {
int len1 = str1.length();
int len2 = str2.length();
int c[][] = new int[len1+1][len2+1];
for (int i = 0; i <= len1; i++) {
for( int j = 0; j <= len2; j++) {
if(i == 0 || j == 0) {
c[i][j] = 0;
} else if (str1.charAt(i-1) == str2.charAt(j-1)) {
c[i][j] = c[i-1][j-1] + 1;
} else {
c[i][j] = max(c[i - 1][j], c[i][j - 1]);
}
}
}
return c[len1][len2];
}
若数组太大无法开下,则用滚动数组
char a[H];//正序
char b[H];//逆序
int c[3][H]; //记录子序列的长度最大值 此处用到了滚动数组 如果开串c[h][h]会超内存(MLE),或改为 short int c[H][H]
int LCS(int m,int n){//求出最长公共子序列的长度
for(int i=0;i<=2;i++){
c[i][0]=0;
}
for(int j=0;j<=n;j++){
c[0][j]=0;
}
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
if(a[i]==b[j])
c[i%2][j]=c[(i-1)%2][j-1]+1;
else{
c[i%2][j]=max(c[(i-1)%2][j],c[i%2][j-1]);
}
}
}
return c[m%2][n];
}
网友评论