c++实现
#include <iostream> // 引入iostream库,可以使用cout和cin等输入输出函数
using namespace std; // 使用命名空间std,简化代码
// LCSLength函数用于计算最长公共子序列的长度
// 参数:m和n分别为两个序列的长度;x和y为两个序列;c和b为二维数组,用于存储计算结果
void LCSLength(int m, int n, char* x, char* y, int** c, int** b) {
// 初始化边界情况
for (int i = 1; i <= m; i++)
c[i][0] = 0;
for (int j = 0; j <= n; j++)
c[0][j] = 0;
// 动态规划计算最长公共子序列的长度
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
// 如果两个序列的当前字符相等
if (x[i] == y[j]) {
c[i][j] = c[i - 1][j - 1] + 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; // 标记选择了x序列的前一个字符
}
else {
c[i][j] = c[i][j - 1]; // 子问题的解为前一个子问题的解
b[i][j] = 3; // 标记选择了y序列的前一个字符
}
}
}
}
// LCS函数用于打印最长公共子序列
// 参数:i和j为当前字符的位置;x为序列;b为二维数组,存储计算结果
void LCS(int i, int j, char* x, int** b) {
// 如果i或j为0,表示已经到达序列的起始位置
if (i == 0 || j == 0) {
return;
}
// 根据b数组的值,判断当前字符是否属于最长公共子序列
if (b[i][j] == 1) {
LCS(i - 1, j - 1, x, b); // 递归打印前一个字符
cout << x[i]; // 打印当前字符
}
else if (b[i][j] == 2) {
LCS(i - 1, j, x, b); // 递归打印前一个字符
}
else {
LCS(i, j - 1, x, b); // 递归打印前一个字符
}
}
// output函数用于打印序列
// 参数:s为序列;n为序列的长度
void output(char* s, int n) {
for (int i = 1; i <= n; i++) {
cout << s[i] << " "; // 打印每个字符
}
cout << endl; // 换行
}
int main() {
// 定义两个序列
char x[] = { ' ', 'A', 'B', 'C', 'B', 'D', 'A', 'B' };
char y[] = { ' ', 'B', 'D', 'C', 'A', 'B', 'A' };
const int M = 7; // 序列x的长度
const int N = 6; // 序列y的长度
// 动态分配二维数组c和b的内存
int** c = new int* [M + 1];
int** b = new int* [M + 1];
for (int i = 0; i <= M; i++) {
c[i] = new int[N + 1];
b[i] = new int[N + 1];
}
// 打印序列x和y
cout << "序列X:" << endl;
output(x, M);
cout << "序列Y:" << endl;
output(y, N);
// 调用LCSLength函数计算最长公共子序列的长度
LCSLength(M, N, x, y, c, b);
// 打印最长公共子序列的长度和内容
cout << "序列X、Y最长公共子序列长度为:" << c[M][N] << endl;
cout << "序列X、Y最长公共子序列为:" ;
LCS(M, N, x, b);
cout << endl;
// 释放动态分配的内存
for (int i = 0; i <= M; i++) {
delete[] c[i];
delete[] b[i];
}
delete[] c;
delete[] b;
return 0;
}