实验问题:
给定两个序列,找出它们最长的公共序列<公共序列不一定连续>
问题分析:
给定两条子序列A={ },B={
}
他们的公共子序列为Z={ }
分为三种情况:
(1) ,则
且
是
和
的最长公共子序列(问题减小);
(2) 若
则
是
和
的最长公共子序列(问题减小);
(3) 若
则
是
和
的最长公共子序列(问题减小)。
数学建模:
建立一个数组c[i][j]来存储A和B的公共子序列,i,j分别用来指向A,B序列。
从而可以递归地求解c[i][j]
对于上面的三种情况分别求解:
(1)如果i=0或j=0即A,B序列有一个已经为0(递归出口)
(2)如果a[i-1]=b[j-1]即序列最后一个元素相同,则c[i][j]=c[i-1][j-1]+1
(3)如果a[i-1]≠b[i-1]即序列最后一个元素不同,则c[i][j]=max(c[i][j-1],c[i-1][j])
填充完c[i][j]之后要求解对应的序列
不同的回溯方法对应不同的最长公共子序列
建立函数BUILD_LCS(k,i,j) 其中k是最长公共子序列的长度,i指向A序列,j指向B序列。
不论哪种回溯方式,当遇到c[i][j]=c[i-1][j](c[i][j-1])时,BUILD_LCS(k,i-1,j)(BUIILD_LCS(k,i,j-1))即未匹配到相等的元素。如果与上右都不等,那么就匹配到相等的元素则BUILD_LCS(k-1,i-1,j-1)移动到对角。
实验代码:
#define _CRT_NO_SECURE_WARNINGS
#include<stdio.h>
#include<iostream>
using namespace std;
int c[100][100] = { 0 };
char a[100] = { '0' };
char b[100] = { '0' };
char res[100] = { '0' };
int max(int a, int b) {
if (a > b) {
return a;
}
if (a < b) {
return b;
}
}
int LSC_LEN(int i, int j) {
if (i == 0 || j == 0) {
c[i][j] = 0;
return 0;
}
else if (a[i - 1] == b[j - 1]) {
c[i][j] = LSC_LEN(i - 1, j - 1) + 1;
}
else {
c[i][j] = max(LSC_LEN(i, j - 1), LSC_LEN(i - 1, j));
}
}
void BUILD_LCS(int k, int i, int j) {
if (i == 0 || j == 0) {
return;
}
if (c[i][j] == c[i - 1][j]) {
BUILD_LCS(k, i - 1, j);
}
else if (c[i][j] == c[i][j - 1]) {
BUILD_LCS(k, i, j - 1);
}
else {
res[k] = a[i - 1];
BUILD_LCS(k - 1, i - 1, j - 1);
}
}
int main() {
int k = 0;
int m = 0;
int n = 0;
cout << "请输入第一段序列:";
for (m = 0;m < 100;m++) {
cin >> a[m];
if (getchar() == '\n') {
break;
}
}
cout << "请输入第二段序列:";
for (n = 0;n < 100;n++) {
cin >> b[n];
if (getchar() == '\n') {
break;
}
}
k = LSC_LEN(m + 1, n + 1);
BUILD_LCS(k, m + 1, n + 1);
cout << "这两段序列为:" << endl;
for (int q = 0;q <= m;q++) {
cout << a[q] << " ";
}
cout << "\n";
for (int j = 0;j <= n;j++) {
cout << b[j] << " ";
}
cout << "\n";
cout << "最大子序列为:" << endl;
for (int p = 1;p <= k;p++) {
cout << res[p] << ' ';
}
cout << "\n";
system("pause");
return 0;
}
测试数据:
第一段序列:a f e d i g h p h
第二段序列:a f d i h h
实验结果:
时间复杂度分析:
若A的序列长为m,B的序列长为n
则时间复杂度为O(m*n)
(A中的元素都要与B中的元素对比)