转载链接:http://www.cnblogs.com/PJQOOO/p/3897745.html
第一步:先计算最长公共子序列的长度。
实现第一步:
设一个C[i][j]: 保存Xi与Yj的LCS的长度。
设X = { x1~xm },Y = { y1~yn }及它们的最长子序列Z = { z1~zk }则:
1、若 xm = yn , 则 zk = xm = yn,且Z[k-1] 是 X[m-1] 和 Y[n-1] 的最长公共子序列
2、若 xm != yn ,且 zk != xm , 则 Z 是 X[m-1] 和 Y 的最长公共子序列
3、若 xm != yn , 且 zk != yn , 则 Z 是 Y[n-1] 和 X 的最长公共子序列
子问题的递归结构:
当 i = 0 , j = 0 时 , c[i][j] = 0
当 i , j > 0 ; xi = yi 时 , c[i][j] = c[i-1][j-1] + 1
当 i , j > 0 ; xi != yi 时 , c[i][j] = max { c[i][j-1] , c[i-1][j] }
第二步:根据长度,然后通过回溯求出最长公共子序列。
实现代码:
1 #include <stdio.h> 2 #include <string.h> 3 #include <math.h> 4 #include <limits.h> 5 #include <algorithm> 6 #include <iostream> 7 #include <ctype.h> 8 #include <iomanip> 9 #include <queue> 10 #include <map> 11 #include <stdlib.h> 12 using namespace std; 13 14 char a[100],b[100],dp[100][100]; 15 16 int LCS(int n,int m){ 17 int i,j; 18 int len=max(n,m); 19 for(i=0;i<=len;i++){ 20 dp[i][0]=0; 21 dp[0][i]=0; 22 } 23 for(i=1;i<=n;i++){ 24 for(j=1;j<=m;j++){ 25 if(a[i-1]==b[j-1]){ 26 dp[i][j]=dp[i-1][j-1]+1; 27 } 28 else{ 29 dp[i][j]=max(dp[i-1][j],dp[i][j-1]); 30 } 31 } 32 } 33 return dp[n][m]; 34 } 35 36 int main() 37 { 38 cin>>a; 39 cin>>b; 40 int n=strlen(a); 41 int m=strlen(b); 42 int k=LCS(n,m); 43 cout<<k<<endl; 44 int i=n-1,j=m-1,count=k; 45 while(count!=0){ 46 if(a[i]==b[j]){ 47 cout<<a[i]; 48 i--; 49 j--; 50 count--; 51 } 52 else if(dp[i][j-1]>dp[i-1][j]){ 53 j--; 54 } 55 else{ 56 i--; 57 } 58 } 59 cout<<endl; 60 }