问题描述
如果Z既是X的子序列,又是Y的子序列,则称Z为X和Y的公共子序列,求Z的最长值
基本思路
-
如果xm = yn,则zk = xm = yn 且 Zk-1是Xm-1和Yn-1的一个LCS
-
如果xm != yn 且 zk != xm,则Z是Xm-1和Y的一个LCS
-
如果xm != yn且 zk!= yn,则Z是X和Yn-1的一个LCS
从底边为1开始记录
源码
/**
* 最长公共子序列
* */
#include <stdio.h>
#include <stdlib.h>
char x[] = {'0', 'A', 'B', 'C', 'B', 'D', 'A', 'B'};
char y[] = {'0', 'B', 'D', 'C', 'A', 'B', 'A'};
int m = 7, n = 6;
int c[10][10];
int b[10][10];
void LCSLength(int m, int n)
{
int i, j;
// 初始化底边为0
for (i = 1; i <= m; i++)
c[i][0] = 0;
for (i = 1; i <= n; i++)
c[0][i] = 0;
// 从底边为1开始计算
for (i = 1; i <= m; i++)
{
for (j = 1; j <= n; j++)
{
// 如果序列元素相等,则把左上的值+1
if (x[i] == y[j])
{
c[i][j] = c[i - 1][j - 1] + 1;
b[i][j] = 1;
}
// 如果不等,则取最大值
else if (c[i - 1][j] >= c[i][j - 1])
{
c[i][j] = c[i - 1][j];
b[i][j] = 2;
}
else
{
c[i][j] = c[i][j - 1];
b[i][j] = 3;
}
}
}
}
void LCS(int i, int j)
{
if (i == 0 || j == 0)
return;
if (b[i][j] == 1)
{
LCS(i - 1, j - 1);
printf("%c ", x[i]);
}
else if (b[i][j] == 2)
LCS(i - 1, j);
else
LCS(i, j - 1);
}
int main(int argc, char const *argv[])
{
LCSLength(m, n);
printf("%d\n", c[7][6]);
LCS(7, 6);
return 0;
}