最长公共子序列
X = {x1, x2, ......, xm}
Y= {y1, y2,......,yn}
希望找出X,Y的一个最长公共子序列
1.描述最有子结构
设Z = {z1, z2,。。。。。。, zk}是X, Y的一个最优解。
当xm = yn时,Zk-1是Xm-1,Yn-1的最优解
当xm != yn时,且xm!=zk,则Zk是Xm-1, Yn的最优解。
当xm != yn时, 且yn!=zk,则Zk
2.递归式(状态转移方程)
d[i,j]表示Xi, Yj的LCS
0 ; i = 0 or j = 0
d[i,j] = d[i-1,j-1] + 1; 当xi = yj
MAX{ d[i-1,j], d[i, j-1] }; 当xi != yj时候
3.自底向上填表计算
4.构造最优解
#include <stdlib.h>
#include <string.h>
void longestCommonSubsequence(char *a, char *b, char *result)
{
int **d; /* working matrix*/
int m = strlen(a), n = strlen(b); /* string length */
int count, i, j;
/* ----- get memory and initialize dope vector ----- */
d = (int **) malloc(sizeof(int)*(m+1));
d[0] = (int *) malloc(sizeof(int)*(m+1)*(n+1));
for (i = 1; i <= m; i++)
d[i] = d[i-1] + n + 1;
/* ------ Clear the dynamic programming table ------ */
d[0][0] = 0;
for (i = 1; i <= m; d[i][0] = 0, i++)
;
for (j = 1; j <= n; d[0][j] = 0, j++)
;
/* --------- dynamic programming technique --------- */
for (i = 1; i <= m; i++) /* for each pair of */
for (j = 1; j <= n; j++) /* chars in strings: */
if (a[i-1] == b[j-1]) /* are they equal ? */
d[i][j] = d[i-1][j-1] + 1; /* one more*/
else if (d[i][j-1] > d[i-1][j]) /* or pick */
d[i][j] = d[i][j-1]; /* a smaller */
else /* neighbor */
d[i][j] = d[i-1][j];
/* -------- finally display the subsequence -------- */
count = d[m][n]; /* d[m][n] is the length */
result[count] = '\0'; /* put a EOS there */
for (i = m,j = n; (i != 0) && (j != 0);) /* R->L odr */
if (d[i][j] == d[i-1][j]) /* are they contribute*/
i--; /* equal counting ? NO, */
else if (d[i][j] == d[i][j-1])
j--; /* NO, backup */
else
{ /* YES, save this character */
result[--count] = a[i-1];
i--, j--; /* backup both string */
}
free(d[0]);
free(d);
}
/* ------------------------------------------------------ */
#include <stdio.h>
#define MAXSIZE 50
void main(void)
{
char a[] = "ABXZWTP01=+C*US";
char b[] = "TX013W+-P12=+CCTXU";
char c[MAXSIZE];
printf("\nLongest Common Subsequence Program");
printf("\n==================================\n");
printf("\nFirst String : %s", a);
printf("\nSecond String : %s", b);
longestCommonSubsequence(a, b, c);
printf("\nL.C.S. String : %s", c);
}