若要求输出所有可能的最长公共子序列,该如何修改LCS算法,用C++实现
时间: 2024-05-10 16:14:17 浏览: 82
最长公共子序列算法C++实现
要输出所有可能的最长公共子序列,需要对LCS算法进行修改,具体方法如下:
1. 在LCS算法中,记录每个格子的状态(来自左上角、来自左边、来自上边),以便回溯时能够找到所有的LCS。
2. 对于每个格子,记录它所代表的两个字符串的子串,以便在回溯时能够输出LCS。
下面是用C语言实现的代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXLEN 100
int lcs[MAXLEN+1][MAXLEN+1]; // 记录LCS的长度
int state[MAXLEN+1][MAXLEN+1]; // 记录每个格子的状态
char str1[MAXLEN+1], str2[MAXLEN+1]; // 两个输入字符串
int len1, len2; // 两个字符串的长度
// 递归输出所有可能的LCS
void print_lcs(int i, int j, char* lcs_str, int lcs_len) {
if (i == 0 || j == 0) {
// 递归结束,输出LCS
for (int k = lcs_len-1; k >= 0; k--)
printf("%c", lcs_str[k]);
printf("\n");
return;
}
if (state[i][j] == 0) {
// 来自左上角,表示str1[i-1]和str2[j-1]在LCS中
lcs_str[lcs_len] = str1[i-1];
print_lcs(i-1, j-1, lcs_str, lcs_len+1);
}
if (state[i][j] == 1) {
// 来自上边,表示str2[j-1]不在LCS中
print_lcs(i, j-1, lcs_str, lcs_len);
}
if (state[i][j] == 2) {
// 来自左边,表示str1[i-1]不在LCS中
print_lcs(i-1, j, lcs_str, lcs_len);
}
}
// 计算LCS
void calc_lcs() {
// 初始化第一行和第一列
for (int i = 0; i <= len1; i++)
lcs[i][0] = 0;
for (int j = 0; j <= len2; j++)
lcs[0][j] = 0;
// 计算LCS
for (int i = 1; i <= len1; i++) {
for (int j = 1; j <= len2; j++) {
if (str1[i-1] == str2[j-1]) {
lcs[i][j] = lcs[i-1][j-1] + 1;
state[i][j] = 0; // 来自左上角
} else {
if (lcs[i-1][j] >= lcs[i][j-1]) {
lcs[i][j] = lcs[i-1][j];
state[i][j] = 2; // 来自左边
} else {
lcs[i][j] = lcs[i][j-1];
state[i][j] = 1; // 来自上边
}
}
}
}
}
int main() {
printf("请输入两个字符串,用空格隔开:");
scanf("%s%s", str1, str2);
len1 = strlen(str1);
len2 = strlen(str2);
calc_lcs();
char lcs_str[MAXLEN+1];
print_lcs(len1, len2, lcs_str, 0);
return 0;
}
```
在这个代码中,`lcs[i][j]`表示`str1[0...i-1]`和`str2[0...j-1]`的LCS长度,`state[i][j]`表示该格子的状态。`print_lcs`函数递归输出所有可能的LCS,`lcs_str`保存当前正在输出的LCS,`lcs_len`表示当前LCS的长度。
阅读全文