步骤:
1.找出最优解性质,并刻画其结构特征。
2.递归定义最优值。
3.以自底向上的方式计算最优值。
4.根据计算最优值时得到的信息,构造最优解。
最长公共子序列:
给定两个序列:
X{x1,x2,x3…xm} m
Y[y1,y2,y3…yn] n
Z{z1,z2…zk} k
- 当xm==yn ----- 推出 ------> xm == yn == zk zk为最长公共子序列
因此 Zk-1 时Xm-1和Yn-1得最长公共子序列 - 当xm != yn zk != xm 时
Zk 就是Xm-1 和 Yn得最长公共子序列 - 当xm != yn zk != yn 时
Zk 就是Xm 和 Yn-1得最长公共子序列
根据以上得出得性质。
i
: 序列X的字符个数
j
: 序列y的字符个数
定义一个二维数组C[i][j]
当i == 0 || j==0
,说明X和Y序列是空的。
则C[i][j] = 0
;
当i > 0 && j > 0
则有 :
X[i] == X[j]
时C[i-1][j-1]+1
;
X[i] != X[j]
时
i > j C[ i-1] [j]
j > i C[j-1] [i-1]
最后取两个的最大值。
得出关系如下 :
递归代码如下:
#include<iostream>
#include<vector>
using namespace std;
int sum = 0;
int LCSLength(const char* x,const char* y, const int m,const int n)
{
sum += 1;
if (m == 0 || n == 0) return 0;
if (x[m]== y[n])
{
return LCSLength(x, y, m - 1, n - 1) + 1;
}
else
{
int xs = LCSLength(x, y, m - 1, n);
int ys = LCSLength(x, y, m, n - 1);
if (xs > ys) { return xs;}
else
{
return ys;
}
}
}
非递归代码:
int NiceLCSLength(const char* x, const char* y, const int m, const int n, vector<vector<int> >& vec,vector<vector<int> > &s)
{
for (int i = 0; i <= m; ++i) vec[i][0] = 0;
for (int j = 0; j <= n; ++j) vec[0][j] = 0;
for (int i = 1; i <= m; ++i)
{
for (int j = 1; j <= n; ++j)
{
sum += 1;
if (x[i] == y[j])
{
vec[i][j] = vec[i - 1][j - 1] + 1;
s[i][j] = 1;
}
else if(vec[i-1][j] >= vec[i][j-1])
{
vec[i][j] = vec[i - 1][j];
s[i][j] = 2;
}
else
{
vec[i][j] = vec[i][j - 1];
s[i][j] = 3;
}
}
}
return vec[m][n];
}
void LCS(int i, int j, const char* X, vector<vector<int> >& s)
{
if (i == 0 || j == 0) return;
if (s[i][j] == 1)
{
LCS(i - 1, j - 1, X, s);
printf("%5c", X[i]);
}
else if (s[i][j] == 2)
{
LCS(i - 1, j, X, s);
}
else
{
LCS(i, j - 1, X, s);
}
}
测试代码:
int main()
{
const char X[] = {"#ABCBDAB"};
const char Y[] = {"#BDCABA"};
int XLen = strlen(X)-1;
int YLen = strlen(Y)-1;
vector<vector<int> > vec(XLen+1,vector<int>(YLen+1,0));
vector<vector<int> > s(XLen + 1, vector<int>(YLen + 1, 0));
// int maxlen = LCSLength(X,Y,XLen,YLen);
// cout << "maxlen = " << maxlen <<endl;
int maxlen1 = NiceLCSLength(X, Y, XLen, YLen, vec,s);
cout << "maxlen1 = " << maxlen1 << " " << sum << endl;
PrintVector(s);
LCS(XLen, YLen, X, s);
}
int main()
{
const char* X = { "#QWABCDEFGHIJJIHGFEDCBAYZ" };
const char* Y = { "#ZYABCDEFGHIJJIHGFEDCBAWQ" };
int XLen = strlen(X)-1;
int YLen = strlen(Y)-1;
vector<vector<int> > vec(XLen+1,vector<int>(YLen+1,0));
vector<vector<int> > s(XLen + 1, vector<int>(YLen + 1, 0));
cout << "maxlen1 = " << maxlen1 << " " << sum << endl;
PrintVector(s);
}