最长公共子序列LCS和最长子串SLCS

来源:互联网 发布:rsa算法原理 一 编辑:程序博客网 时间:2024/06/05 11:08

最长子序列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;}
原创粉丝点击