找出X={x1,x2,x,3,x4,x5…….} Y={y1,y2,y3,y4……}最长公共子序列
2个序列的最长公共子序列包含了这2个序列的前缀的最长公共子序列。因此,最长公共子序列问题具有最优子结构性质。
由最优子结构性质可建立递归关系如下:
void LSCLengh(int m, int n, char x[], char y[]) {
//m是x数组长度
//n是y数组长度
//c[m+1][n+1]数组是辅助空间,记录
//b[m+1][n+1]数组记录 1-LeftUp、2-UP、3-Left
int i, j;
for (i = 0; i <= m; i++)
c[i][0] = 0;
for (i = 1; i <= n; i++)
c[0][i] = 0;//边缘初始化
for (i = 1; i <= m; i++) {
for (j = 1; j <= n; j++)
{
if (x[i] == y[j])
{
c[i][j] = c[i - 1][j - 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;
}
else
{
c[i][j] = c[i][j - 1];
b[i][j] = 3;
}
}
}
}
//构造最长公共子序列
void lcs(int i, int j, char x[])
{
if (i == 0 || j == 0)
return;
if (b[i][j] == 1)
{
lcs(i - 1, j - 1, x);
cout << x[i];
}
else if (b[i][j] == 2)
lcs(i - 1, j, x);
else
lcs(i, j - 1, x);
}
时间复杂度:O(mn)
在算法lcsLength和lcs中,可进一步将数组b省去。事实上,数组元素c[i][j]的值仅由c[i-1][j-1],c[i-1][j]和c[i][j-1]这3个数组元素的值所确定。对于给定的数组元素c[i][j],可以不借助于数组b而仅借助于c本身在时间内确定c[i][j]的值是由c[i-1][j-1],c[i-1][j]和c[i][j-1]中哪一个值所确定的。
如果只需要计算最长公共子序列的长度,则算法的空间需求可大大减少。事实上,在计算c[i][j]时,只用到数组c的第i行和第i-1行。因此,用2行的数组空间就可以计算出最长公共子序列的长度。进一步的分析还可将空间需求减至O(min(m,n))。
#include<iostream>
using namespace std;
int c[7 + 1][6 + 1];
int b[7 + 1][6 + 1];
void LSCLengh(int m, int n, char x[], char y[]) {
//m是x数组长度
//n是y数组长度
//c[m+1][n+1]数组是辅助空间,记录
//b[m+1][n+1]数组记录 1-LeftUp、2-UP、3-Left
int i, j;
for (i = 0; i <= m; i++)
c[i][0] = 0;
for (i = 1; i <= n; i++)
c[0][i] = 0;//边缘初始化
for (i = 1; i <= m; i++) {
for (j = 1; j <= n; j++)
{
if (x[i] == y[j])
{
c[i][j] = c[i - 1][j - 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;
}
else
{
c[i][j] = c[i][j - 1];
b[i][j] = 3;
}
}
}
cout << endl;
for (i = 1; i <= m; i++) {
cout << " ";
for (j = 1; j <= n; j++)
cout << c[i][j] << " ";
cout << endl;
}
cout << endl;
for (i = 1; i <= m; i++) {
cout << " ";
for (j = 1; j <= n; j++)
cout << b[i][j] << " ";
cout << endl;
}
}
//构造最长公共子序列
void lcs(int i, int j, char x[])
{
if (i == 0 || j == 0)
return;
if (b[i][j] == 1)
{
lcs(i - 1, j - 1, x);
cout << x[i];
}
else if (b[i][j] == 2)
lcs(i - 1, j, x);
else
lcs(i, j - 1, x);
}
int main() {
char x[] = {' ', 'A','B','C','B','D','A','B'};
char y[] = {' ' ,'B','D','C','A','B','A' };
LSCLengh(7, 6, x, y);
lcs(7, 6, x);
return 0;
}
运行结果: