经典算法题目——最长公共子序列问题
2010-08-02 11:18
417 查看
给定两个序列
X = { x1 , x2 , ... , xm }
Y = { y1 , y2 , ... , yn }
求X和Y的一个最长公共子序列
举例
X = { a , b , c , b , d , a , b }
Y = { b , d , c , a , b , a }
最长公共子序列为
LSC = { 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 = { x1 , x2 , ... , xm }
Y = { y1 , y2 , ... , yn }
求X和Y的一个最长公共子序列
举例
X = { a , b , c , b , d , a , b }
Y = { b , d , c , a , b , a }
最长公共子序列为
LSC = { 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] }
#include "iostream.h" #include "iomanip.h" #define max 100 void LCSLength(int m,int n,char *x,char *y,char *b) { int i,j,k; int c[max][max]; for(i=1;i<=m;i++) c[i][0]=0; for(i=1;i<=n;i++) c[0][i]=0; for(i=1;i<=m;i++) { for(j=1;j<=n;j++) { if(x[i-1]==y[j-1]) { c[i][j]=c[i-1][j-1]+1; k=i*(n+1)+j; b[k]='//'; } else if(c[i-1][j]>=c[i][j-1]) { c[i][j]=c[i-1][j]; k=i*(n+1)+j; b[k]='|'; } else { c[i][j]=c[i][j-1]; k=i*(n+1)+j; b[k]='-'; } } } } void LCS(int i,int j,char *x,char *b,int width) { if(i==0||j==0) return; int k=i*(width+1)+j; if(b[k]=='//') { LCS(i-1,j-1,x,b,width); cout<<x[i]<<endl; } else if(b[k]=='|') LCS(i-1,j,x,b,width); else LCS(i,j-1,x,b,width); } void main() { char x[max] = { 'a','b','c','b','d','a','b'}; char y[max] = { 'b','d','c','a','b','a'}; int m=7; int n=6; char b[max] = { 0 }; LCSLength(m,n,x,y,b); LCS(m,n,x,b,n); cout<<endl<<endl; }
相关文章推荐
- 【算法导论学习-29】动态规划经典问题02:最长公共子序列问题(Longest common subsequence,LCS)
- 【经典算法】:最长公共子序列(LCS问题,用遍历实现)
- 【算法导论学习-29】动态规划经典问题02:最长公共子序列问题(Longest common subsequence,LCS)
- 经典算法题目:Cracking the coding interview 问题与解答
- 精选微软经典的算法面试100题(第1-20题) -代码详解(题目选自“结构之法”大侠的博客,答案都是本菜鸟自己做的)
- 【经典问题】二维动态规划问题:求最长公共子序列LCS
- 经典算法回顾 (Java版)—— 八皇后问题
- 经典面试问题:12小球问题算法(文档)
- 经典面试问题:12小球问题算法(源码)
- NYOJ 1058 部分和问题(经典题目dfs)
- 算法竞赛入门经典-开灯问题
- 括号匹配问题与经典笔试面试题目解析
- 九度OJ:题目1030:毕业bg(经典背包问题)
- 经典算法之二维数组中的查找问题
- 算法的经典问题,求最长回文子串,最长重复字串
- 经典算法之0-1背包问题
- 经典算法之—背包问题
- 约瑟夫环问题,一道经典的数据结构题目
- 经典算法(3)——最大间隙问题(线性时间算法)
- 算法知识之最长公共子序列问题(动态规划)