最長公共子序列問題動態規劃
阿新 • • 發佈:2018-11-04
最長公共子序列問題:若給定序列X={x1,x2,…,xm},則另一序列Z={z1,z2,…,zk},是X的子序列是指存在一個嚴格遞增下標序列{i1,i2,…,ik}使得對於所有j=1,2,…,k有:zj=xij。例如,序列Z={B,C,D,B}是序列X={A,B,C,B,D,A,B}的子序列,相應的遞增下標序列為{2,3,5,7}。
給定2個序列X和Y,當另一序列Z既是X的子序列又是Y的子序列時,稱Z是序列X和Y的公共子序列。
給定2個序列X={x1,x2,…,xm}和Y={y1,y2,…,yn},找出X和Y的最長公共子序列。
#include<stdio.h> #include<string.h> #define MAXLEN 100 void LCSLength(char *x,char *y,int m, int n,int c[][MAXLEN],int b[][MAXLEN]) { int i,j; for(i=0;i<=m;i++){ c[i][0]=0; } for(j=1;j<=n;j++){ c[0][j]=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; //c[i][j]來源於前一行前一列,即↖ b[i][j]=0; } else if(c[i-1][j]>=c[i][j-1]){ c[i][j]=c[i-1][j]; //c[i][j]來源於前一行前一列,即↑ b[i][j]=1; } else{ c[i][j]=c[i][j-1]; //c[i][j]來源於前一行前一列,即← b[i][j]=-1; } } } } void PrintLCS(int b[][MAXLEN],char *x,int i,int j) { if(i==0||j==0){ return ; } if(b[i][j]==0){ PrintLCS(b,x,i-1,j-1); printf("%c ",x[i-1]); } else if(b[i][j]==1){ PrintLCS(b,x,i-1,j); } else{ PrintLCS(b,x,i,j-1); } } void main() { char x[MAXLEN]; char y[MAXLEN]; int b[MAXLEN][MAXLEN]; int c[MAXLEN][MAXLEN]; int m,n; printf("輸入第一個字串:\n"); gets(x); printf("輸入第二個字串:\n"); gets(y); m=strlen(x); n=strlen(y); LCSLength(x,y,m,n,c,b); printf("最長公共子序列為:"); PrintLCS(b,x,m,n); getchar(); }