最長子序列LCS
#include <iostream>
using namespace std;
#define LEFT_UP 'a'
#define UP 'b'
#define LEFT 'c'
//求最長子序列長度
int Lcs_length(string s1, string s2, int* &num, char* &seq)
{
int m = s1.length();
int n = s2.length();
int dim_1 = n + 1;
for(int i = 0; i <= m; ++i)
{
*(num + i * dim_1 + 0) = 0;
}
for(int i = 0; i <= n; ++i)
{
*(num + 0 * dim_1 + i) = 0;
}
for(int i = 1; i <= m; ++i)
{
for(int j = 1; j <= n; ++j)
{
if(s1[i-1] == s2[j-1])
{
*(num + i * dim_1 + j) = *(num + (i-1) * dim_1 + j-1) + 1;
*(seq + i * dim_1 + j) = LEFT_UP;
}
else if(*(num + (i-1) * dim_1 + j) >= *(num + i * dim_1 + j-1))
{
*(num + i * dim_1 + j) = *(num + (i-1) * dim_1 + j);
*(seq + i * dim_1 + j) = UP;
}
else
{
*(num + i * dim_1 + j) = *(num + i * dim_1 + j-1);
*(seq + i * dim_1 + j)= LEFT;
}
}
}
return *(num + m * dim_1 + n);
}
//輸出最長公共子序列
void Lcs(string s1, char* seq, int i, int j, int dim)
{
if(i ==0 || j == 0)
{
return;
}
if(*(seq + i * dim + j) == LEFT_UP)
{
Lcs(s1, seq, i-1, j-1, dim);
cout << s1[i-1];
}
else if(*(seq + i * dim + j) == UP)
{
Lcs(s1, seq, i-1, j, dim);
}
else
{
Lcs(s1, seq, i, j-1, dim);
}
}
int main()
{
string s1, s2;
cin >> s1;
cin >> s2;
int* num = new int[(s1.length()+1)*(s2.length()+1)]; //保存當前最大子序列長度
char* seq = new char[(s1.length()+1)*(s2.length()+1)]; //保存軌跡
int len = Lcs_length(s1, s2, num, seq);
cout << "longest length " << len << endl;
//求最長公共子序列
Lcs(s1, seq, s1.length(), s2.length(), s2.length()+1);
return 0;
}
最長子串SLCS是特殊的LCS,因此只需要在LCS的基礎上稍作修改即可
#include <iostream>
using namespace std;
#define LEFT_UP 'a'
#define UP 'b'
#define LEFT 'c'
struct Pos //最長串的位置
{
int i;
int j;
}p1;
//求最長子序列長度
int Lcs_length(string s1, string s2, int* &num, char* &seq)
{
int m = s1.length();
int n = s2.length();
int dim_1 = n + 1;
int max_len = 0;
for(int i = 0; i <= m; ++i)
{
*(num + i * dim_1 + 0) = 0;
}
for(int i = 0; i <= n; ++i)
{
*(num + 0 * dim_1 + i) = 0;
}
for(int i = 1; i <= m; ++i)
{
for(int j = 1; j <= n; ++j)
{
if(s1[i-1] == s2[j-1])
{
*(num + i * dim_1 + j) = *(num + (i-1) * dim_1 + j-1) + 1;
if(*(num + i * dim_1 + j) > max_len)
{
max_len = *(num + i * dim_1 + j);
p1.i = i;
p1.j = j;
}
*(seq + i * dim_1 + j) = LEFT_UP;
}
else
{
*(num + i * dim_1 + j) = 0;
*(seq + i * dim_1 + j) = UP;
}
}
}
return max_len;
}
//求最長公共子序列
void Lcs(string s1, char* seq, int i, int j, int dim)
{
if(i ==0 || j == 0)
{
return;
}
if(*(seq + i * dim + j) == LEFT_UP)
{
Lcs(s1, seq, i-1, j-1, dim);
cout << s1[i-1];
}
}
int main()
{
string s1, s2;
cin >> s1;
cin >> s2;
int* num = new int[(s1.length()+1)*(s2.length()+1)]; //保存當前最大子序列長度
char* seq = new char[(s1.length()+1)*(s2.length()+1)]; //保存軌跡
int len = Lcs_length(s1, s2, num, seq);
cout << "longest length " << len << endl;
//求最長公共子序列
Lcs(s1, seq, p1.i, p1.j, s2.length()+1);
return 0;
}