给定2个序列X={x1,x2,…,xm}和Y={y1,y2,…,yn},用动态规划算法找出X和Y的最长公共子序列,用C/C++实现该算法。
时间: 2024-05-02 07:23:30 浏览: 67
以下是C语言实现的最长公共子序列算法:
```c
#include <stdio.h>
#include <string.h>
#define MAXLEN 100
int max(int a, int b) {
return (a > b) ? a : b;
}
int LCS(char* X, char* Y, int m, int n, int L[MAXLEN + 1][MAXLEN + 1]) {
int i, j;
for (i = 0; i <= m; i++) {
for (j = 0; j <= n; j++) {
if (i == 0 || j == 0)
L[i][j] = 0;
else if (X[i - 1] == Y[j - 1])
L[i][j] = L[i - 1][j - 1] + 1;
else
L[i][j] = max(L[i - 1][j], L[i][j - 1]);
}
}
return L[m][n];
}
void printLCS(char* X, char* Y, int m, int n, int L[MAXLEN + 1][MAXLEN + 1]) {
int index = L[m][n];
char lcs[index + 1];
lcs[index] = '\0';
int i = m, j = n;
while (i > 0 && j > 0) {
if (X[i - 1] == Y[j - 1]) {
lcs[--index] = X[i - 1];
i--;
j--;
}
else if (L[i - 1][j] > L[i][j - 1])
i--;
else
j--;
}
printf("LCS of %s and %s is %s\n", X, Y, lcs);
}
int main() {
char X[MAXLEN], Y[MAXLEN];
int L[MAXLEN + 1][MAXLEN + 1];
int m, n, len;
printf("Enter first string: ");
scanf("%s", X);
printf("Enter second string: ");
scanf("%s", Y);
m = strlen(X);
n = strlen(Y);
len = LCS(X, Y, m, n, L);
printf("Length of LCS of %s and %s is %d\n", X, Y, len);
printLCS(X, Y, m, n, L);
return 0;
}
```
该算法使用一个二维数组 L 来记录子序列的长度。其中,L[i][j]表示序列 X[0...i-1] 和 Y[0...j-1] 的最长公共子序列的长度。在算法的实现中,我们首先初始化 L 中的第一行和第一列为 0。然后,我们从左到右,从上到下扫描 L 中的每个元素。如果 X[i-1] 等于 Y[j-1],那么 L[i][j] 就等于 L[i-1][j-1] 加上 1,否则 L[i][j] 就等于 L[i-1][j] 和 L[i][j-1] 中的较大值。最后,我们返回 L[m][n],即序列 X 和 Y 的最长公共子序列的长度。
要输出最长公共子序列,我们可以使用一个类似于回溯的方法。从 L[m][n] 开始,我们检查 L[i-1][j] 和 L[i][j-1] 中的值,如果它们中有一个等于 L[i][j],那么我们就向相应的方向移动。如果 X[i-1] 等于 Y[j-1],那么我们就将 X[i-1] 添加到结果字符串中,然后向左上角移动。最终,我们就可以得到 X 和 Y 的最长公共子序列。
阅读全文