最长公共子序列的C++实现---附二维指针的使用方法

想了挺久到底第一篇在这儿的博客写什么好,刚好这两天又一次看到动态规划的LCS算法觉得还是有点意思的,就拿来写了写,第一篇博客就发它吧。

#include<iostream>

#include<iomanip>

using namespace std;

//tag标志,0为左斜上,1取左,2取上;count为最长公共子序列计数

//计算最长公共子序列长度

void LCS_Length(char *X, char *Y, int *count[],int *tag[],int length_X, int length_Y)

{

    //第一排第一列全部是0

    for (int i = 0; i < length_X+1; i++)

    {

        count[i][0] = 0;

    }

    for (int i = 0; i < length_Y+1; i++)

    {

        count[0][i] = 0;

    }



    for (int i = 1; i <= length_X; i++)

    {

        for (int j = 1; j <= length_Y; j++)

        {

            if (X[i-1] == Y[j - 1])

            {

                count[i][j] = count[i-1][j-1]+1;

                tag[i][j] = 0;

            }

            //否则取较大的值

            else if(count[i-1][j] > count[i][j-1])

            {

                count[i][j] = count[i-1][j];

                tag[i][j] = 1;

            }

            else

            {

                count[i][j] = count[i][j-1];

                tag[i][j] = 2;

            }

        }

    }

}

//打印最长公共子序列元素

void Print_LCS(int *tag[],char *X,int Length_X, int Length_Y)

{

    if (Length_X == 0 || Length_Y == 0)

    {

        return ;

    } 

    int i = Length_X, j = Length_Y;

    if (tag[i][j] == 0)

    {

        cout<<X[i-1]<<setw(4);

        Print_LCS(tag,X,i-1,j-1);

    }

    else if(tag[i][j] == 1)

    {

        Print_LCS(tag,X,i-1,j);

    }

    else

    {

        Print_LCS(tag,X,i,j-1);

    }

}



int main()

{

    //先人为设置两个序列

    char *X = "BDCABA";

    char *Y = "ABCBDA";

    int *count[7];

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

    {

        count[i] = new int[7];       //因为第一行第一列全为0,所以总共七行七列

    }

    int *tag[7];

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

    {

        tag[i] = new int[7];

    }

    LCS_Length(X,Y,count,tag,strlen(X),strlen(Y));

    cout<<"最大子序列数为"<<count[6][6]<<endl;

    /****************************************

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

    {

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

        {

            cout<<count[i][j]<<setw(3);

        }

        cout<<endl;

    }

    *****************************************/

    Print_LCS(tag,X,strlen(X),strlen(Y));

    cout<<endl;

    return 0;

}

 

  主要函数有两个,一个函数是做出保存最长公共子序列的元素个数的矩阵,这里给出的示例中,两个字符串都各6个字符,所以给出的是7行7列矩阵(第一行第一列全为零)。

最长公共子序列的C++实现---附二维指针的使用方法

另外一个函数即为打印函数,从矩阵右下角一位开始遍历到[0][0]位,凡是遇到tag[i][j]标志为0则将该位的字符打印出来。算法比较简单易懂,具体可以参考《算法导论》。

 

下面补充说一个问题:二维指针到底怎么用。比如前面的二维数组初始化,如果我希望能够通过字符串的长度来给我的二维数组定义大小,而不是用常数来指定,使得我们可以通过strlen()函数来定义长度,那么就要用到二维指针。

注意:int *Arr[strlen(str)];这种声明方式是不正确的,编译器会提示错误,数组的声明必须使用常量。下面给出正确的示例:

        /***********************************************

    //华丽丽的分割线--------------------------------

    二维指针到底怎么用

    int *(*ptr) = new int*[strlen(X)];

    for (int i = 0; i < strlen(X); i++)

    {

        ptr[i] = new int[strlen(X)];

    }

    ptr[2][3] = 0;

    cout<<ptr[2][3]<<endl;

    **********************************************/

 

你可能感兴趣的:(C++)