zoukankan      html  css  js  c++  java
  • 最长公共子序列的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列矩阵(第一行第一列全为零)。

    另外一个函数即为打印函数,从矩阵右下角一位开始遍历到[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;
        **********************************************/
  • 相关阅读:
    DEV获取GridControl当前行
    03002_Http请求协议分析
    雷林鹏分享:CSS 组合选择符
    雷林鹏分享:Redis 字符串(String)
    雷林鹏分享:Redis 键(key)
    雷林鹏分享:CSS 布局
    雷林鹏分享:CSS Float(浮动)
    雷林鹏分享:CSS 布局
    雷林鹏分享:CSS Position(定位)
    雷林鹏分享:CSS Display(显示) 与 Visibility(可见性)
  • 原文地址:https://www.cnblogs.com/nerohwang/p/3480448.html
Copyright © 2011-2022 走看看