最长公共子序列

来源:互联网 发布:淘宝lee代购是正品吗 编辑:程序博客网 时间:2024/06/01 22:38

最长公共子序列(longest common sequence)和最长公共子串(longest common substring)不是一回事儿。什么是子序列呢?即一个给定的序列的子序列,就是将给定序列中零个或多个元素去掉之后得到的结果。

我们可以知道递推公式为:

               0;                                i=0 or j=0;

c[i][j]=     c[i-1][j-1]+1;                 i,j>0;xi=yi;

              max{c[i][j-1],c[i-1][j]};    i,j>0;xi!=yi;

递归法解决:

#include<stdio.h>#include<string.h>int maxL(char *x,char *y,int i,int j){int t1,t2;if(i==-1||j==-1)return 0;if(x[i]==y[j])return maxL(x,y,i-1,j-1)+1;else{t1=maxL(x,y,i-1,j);t2=maxL(x,y,i,j-1);return t1>t2?t1:t2;}}int main(){char *x="ABCBDAB",*y="BDCABA";printf("最大子序列长度:%d\n",maxL(x,y,lenx,leny));return 0;}
动态规划法解决:

int main(){char *x="ABCBDAB",*y="BDCABA";int **c;int lenx,leny;lenx=strlen(x);leny=strlen(y);c=new int *[lenx+1];for(int i=0;i<lenx+1;i++)c[i]=new int[leny+1];for(int i=0;i<lenx+1;i++)c[i][0]=0;for(int i=0;i<leny+1;i++)c[0][i]=0;for(int i=1;i<lenx+1;i++)for(int j=1;j<leny+1;j++){if(x[i-1]==y[j-1])c[i][j]=c[i-1][j-1]+1;elsec[i][j]=c[i-1][j]>c[i][j-1]?c[i-1][j]:c[i][j-1];}printf("最大子序列长度:%d",c[lenx][leny]);return 0;}
备忘录法解决:

int **c;int maxL(char *x,char *y,int i,int j){int t1,t2,result;if(c[i][j]>=0)return c[i][j];if(x[i-1]==y[j-1])result=maxL(x,y,i-1,j-1)+1;else{t1=maxL(x,y,i-1,j);t2=maxL(x,y,i,j-1);result=t1>t2?t1:t2;}c[i][j]=result;return result;}int main(){char *x="ABCBDAB",*y="BDCABA";int lenx,leny;lenx=strlen(x);leny=strlen(y);c=new int *[lenx+1];for(int i=0;i<lenx+1;i++)c[i]=new int[leny+1];for(int i=0;i<lenx+1;i++)for(int j=0;j<leny+1;j++)c[i][j]=-1;for(int i=0;i<lenx+1;i++)c[i][0]=0;for(int i=0;i<leny+1;i++)c[0][i]=0;printf("最大子序列长度:%d\n",maxL(x,y,lenx,leny));printf("%d",c[lenx][leny]);return 0;}