动态规划-最长公共子序列

来源:互联网 发布:ugg和jumbougg知乎 编辑:程序博客网 时间:2024/06/09 16:21

最长公共子序列,是动态规划的一个典型例题。相比原来的遍历查找,优化明显。

1⃣️、两个序列--Am,Bn,如果Am=Bn,则再去Am-1,Bn-1;

2⃣️、An!=Bm,找其中最大组,即max{{An,Bm-1},{An-1,Bm}};

3⃣️、两者其中一个为空,则有CLS=0;

简单应用-----------------------------------医学中DNA相同对比,找出相同的序列

涉及算法:

int b[N][N];

int CSL_Length(Data x[],Data y[],int length1,int length2)

{

    int n=length1;

    int m=length2;

    for(int i=0;i<n;i++)

        for(int j=0;j<m;j++)

            b[i][j]=0;

    int c[n+1][m+1];

    for(int i=0;i<n;i++)

        c[i][0]=0;

    for(int j=0;j<m;j++)

        c[0][j]=0;

    for(int i=0;i<n;i++)

        for(int j=0;j<m;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;

    }

    return c[n-1][m-1];

}

-------时间复杂度O(n*m),这里其实还有优化之处,后期更新。

输出----------

void searchList(Data x[],int i,int j)

{

    if(b[i][j]==0)return;

    if(b[i][j]==1)

    {

        searchList(x, i-1, j-1);

        printf("%c",x[i]);

    }

    else if(b[i][j]==2)

    {

        searchList(x, i-1, j);

        

    }

    else

    {

        searchList(x, i, j-1);

    }

}

--------------时间复杂度为O(m+n)

用例测试:

char x[8]={'a','a','c','d','e','f'};

    char y[8]={'a','b','c','f','e','f','m','\''};

    printf("the CLS is %d\n",CSL_Length(x,y,6,8));

    searchList(x, 5, 7);

    printf("\n");

输出:


其中还有b数组空间其实有浪费,可以去掉。还有递归调用是会用到环境栈,其中空间远比遍历什么的浪费。