用c语言实现编程要求 求字符串序列“ABCDBAB”和“BDCABA”的最长公共子序列 解题思路: 递推关系分析: 设 A=“a0,a1,…,am−1”,B=“b0,b1,…,bn−1”,Z=“z0,z1,…,zk−1” 为它们的最长公共子序列。 有以下结论: 1)如果am−1=bn−1,则zk−1=am−1=bn−1,且“z0,z1,…,zk−2”是“a0,a1,…,am−2”和“b0,b1,…,bn−2”的一个最长公共子序列; 2)如果am−1=bn−1,则若zk−1=am−1,蕴涵“z0,z1,…,zk−1”是“a0,a1,…,am−2”和“b0,b1,…,bn−1”的一个最长公共子序列; 3)如果am−1=bn−1,则若zk−1=bn−1,蕴涵“z0,z1,…,zk−1”是“a0,a1,…,am−1”和“b0,b1,…,bn−2”的一个最长公共子序列。 定义c[i][j]为序列“a0,a1,…,ai−1”和“b0,b1,…,bj−1”的最长公共子序列的长度,计算c[i][j]可递归地表述如下: 1)c[i][j]=0 如果i=0或j=0; 2)c[i][j]=c[i−1][j−1]+1 如果i,j>0,且a[i−1]=b[j−1]; 3)c[i][j]=max(c[i][j−1],c[i−1][j]) 如果i,j>0,且a[i−1]=b[j−1]。 由二维数组c的递归定义,c[i][j]的结果依赖于c[i−1][j−1],c[i−1][j]和c[i][j−1]。可以从c[m][n]开始,跟踪c[i][j]结果的产生过程,从而逆向构造出最长公共子序列。 测试说明 平台会对你编写的代码进行测试: 测试输入: a=“ABCDBAB” b=“BDCABA” 输出示例: BCBA
时间: 2024-01-01 10:04:36 浏览: 94
以下是使用 C 语言实现求解两个字符串的最长公共子序列的代码示例:
```c
#include <stdio.h>
#include <string.h>
#define MAX_LEN 100
int c[MAX_LEN + 1][MAX_LEN + 1];
void lcs(char* a, char* b, char* result) {
int m = strlen(a);
int n = strlen(b);
// 初始化 c 数组
for (int i = 0; i <= m; i++) {
c[i][0] = 0;
}
for (int j = 1; j <= n; j++) {
c[0][j] = 0;
}
// 计算 c 数组
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (a[i - 1] == b[j - 1]) {
c[i][j] = c[i - 1][j - 1] + 1;
} else {
c[i][j] = (c[i - 1][j] > c[i][j - 1]) ? c[i - 1][j] : c[i][j - 1];
}
}
}
// 逆向构造最长公共子序列
int i = m;
int j = n;
int k = 0;
while (i > 0 && j > 0) {
if (a[i - 1] == b[j - 1]) {
result[k] = a[i - 1];
i--;
j--;
k++;
} else if (c[i - 1][j] >= c[i][j - 1]) {
i--;
} else {
j--;
}
}
// 反转最长公共子序列
for (int l = 0; l < k / 2; l++) {
char temp = result[l];
result[l] = result[k - l - 1];
result[k - l - 1] = temp;
}
result[k] = '\0';
}
int main() {
char a[MAX_LEN + 1] = "ABCDBAB";
char b[MAX_LEN + 1] = "BDCABA";
char result[MAX_LEN + 1];
lcs(a, b, result);
printf("最长公共子序列为:%s\n", result);
return 0;
}
```
代码中的 `lcs` 函数接受两个字符串参数 `a` 和 `b`,以及一个结果字符串参数 `result`,用于存放最长公共子序列。在函数中,首先根据递推关系分析初始化了二维数组 `c`,然后计算了 `c` 数组。最后,根据 `c` 数组逆向构造最长公共子序列,并将其反转存放到 `result` 参数中。在 `main` 函数中,我们给出了测试用例,并输出了最长公共子序列。
阅读全文