最长公共子序列问题
来源:互联网 发布:用友软件使用说明书 编辑:程序博客网 时间:2024/06/06 17:14
大部分为转载,在此基础上小编总结了一下
问题描述:
最长公共子序列也称作最长公共子串(不要求连续),英文缩写为LCS(Longest Common Subsequence)。其定义是,一个序列 S ,如果分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最长的,则 S 称为已知序列的最长公共子序列。
例如:X(A,B,C,B,D,A,B)
Y(B,D,C,A,B,A)
那么最长公共子序列就是:B,C,B,A
算法设计:用动态规划方法解决
最长公共子序列的结构:
设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] }
还是以:X(A,B,C,B,D,A,B)
Y(B,D,C,A,B,A) 为例
看下面的图:
源代码一:
/*ABCBDABBDCABA*/#include <iostream>#include<string.h>#include<algorithm>using namespace std;#define N 105int dp[N+1][N+1];char str1[N],str2[N];char str[N];//函数功能:获取两个字符串的最长公共子序列的数目//len1:字符串1的长度//len2:字符串2的长度int LCSL(int len1,int len2){ int i,j; int len=max(len1,len2); for(i=0; i<=len1; i++) { //dp[i][0]=0;//y为空字符串 dp[i][0]=0;//x为空字符串 } for(i=0; i<=len2; i++) { dp[0][i]=0;//y为空字符串 // dp[0][i]=0;//x为空字符串 } for(i=1; i<=len1; i++) { for(j=1; j<=len2; j++) { if(str1[i-1]==str2[j-1]) { dp[i][j]=dp[i-1][j-1]+1; } else { dp[i][j] = max(dp[i - 1][ j ] , dp[i][j - 1]) ; } } } return dp[len1][len2];}char * build_LCSL(char *str,char *str1,char *str2){ int i=strlen(str1);//获取字符串1的长度 int j=strlen(str2);//获取字符串2的长度 int k=LCSL(i,j); str[k]='\0'; while(k>0) if(dp[i][j]==dp[i-1][j]){ i--; }else if(dp[i][j]==dp[i][j-1]){ j--; }else{ k--; str[k]=str1[i-1]; i--; j--; } return str;}int main(){ while(cin>>str1>>str2) { /* int len1=strlen(str1);//获取字符串1的长度 int len2=strlen(str2);//获取字符串2的长度 cout<<LCSL(len1,len2)<<endl; */ cout<<build_LCSL(str,str1,str2)<<endl; } return 0;}
</pre><pre name="code" class="cpp">
代码二:转载
/*ABCBDABBDCABA*/#include <iostream>#include<cstring>#include<stdio.h>#include<algorithm>using namespace std;const int MAXSTRLEN = 1000;char a[MAXSTRLEN], b[MAXSTRLEN];int dp[MAXSTRLEN][MAXSTRLEN], path[MAXSTRLEN][MAXSTRLEN];///求序列x和y的LCS,path保存路径指向,以方便打印公共子序列int Lcs(char x[], char y[]){ int i, j, len1 = strlen(x + 1), len2 = strlen(y + 1); memset(dp, 0, sizeof(dp)); for (i = 1; i <= len1; ++i) for (j = 1; j <= len2; ++j) { if (x[i] == y[j]) dp[i][j] = dp[i - 1][j - 1] + 1, path[i][j] = 1; else if (dp[i - 1][j] >= dp[i][j - 1]) dp[i][j] = dp[i - 1][j], path[i][j] = 2; else dp[i][j] = dp[i][j - 1], path[i][j] = 3; } return dp[len1][len2];}///打印LCSvoid PrintLcs(int i, int j){ if (i == 0 || j == 0) return; if (path[i][j] == 1) { PrintLcs(i - 1, j - 1); putchar(a[i]); } else if (path[i][j] == 2) PrintLcs(i - 1, j); else PrintLcs(i, j - 1);}int main(){ while (gets(a + 1)) { gets(b + 1); printf("%d\n", Lcs(a, b)); PrintLcs(strlen(a + 1), strlen(b + 1)); putchar(10); } return 0;}
0 0
- 最长公共子序列问题
- 最长公共子序列问题
- 最长公共子序列问题
- 最长公共子序列问题
- 最长公共子序列问题
- 最长公共子序列问题
- 最长公共子序列问题
- 最长公共子序列问题
- 最长公共子序列问题
- 最长公共子序列问题
- 最长公共子序列问题
- 最长公共子序列问题
- 最长公共子序列问题
- 最长公共子序列问题
- 最长公共子序列问题
- 最长公共子序列问题
- 最长公共子序列问题
- 最长公共子序列问题
- Add Binary
- java乱码和转码问题
- 用chrome浏览器调试flex程序
- 微软、Google等公司的面试题及解答、第161-170题
- JMeter 创建随机删除脚本
- 最长公共子序列问题
- Binary Tree Postorder Traversal
- Android Fragment 真正的完全解析(上)
- 多线程
- iOS 实现解压缩
- jQuery.Autocomplete实现自动完成功能
- #LeetCode#SubSets & SubSetsII
- inux下socket编程实例
- 中国渠道销售管理模式特点分析