zoukankan      html  css  js  c++  java
  • 最长公共子串

    题:给定两个字符串X,Y,求二者最长的公共子串,例如X=[aaaba],Y=[abaa]。二者的最长公共子串为[aba],长度为3。

    1 基本算法
    其实对于最长公共子串,还是比较简单易想的,因为子串是连续的,这就方便了很多。
    最直接的方法就是用X每个子串与Y的每个子串做对比,求出最长的公共子串。

    2  DP方案
    既然最长公共子串是最长公共子序列的变体,那么最长公共子串是不是也可以用动态规划来求解呢?
    我们还是像之前一样“从后向前”考虑是否能分解这个问题,在最大子数组和中,
    我们也说过,对于数组问题,可以考虑“如何将arr[0,...i]的问题转为求解arr[0,...i-1]的问题”,
    类似最长公共子序列的分析,这里,我们使用dp[i][j]表示 以x[i]和y[j]结尾的最长公共子串的长度,
    因为要求子串连续,所以对于X[i]与Y[j]来讲,它们要么与之前的公共子串构成新的公共子串;要么就是不构成公共子串。
    故状态转移方程
    X[i] == Y[j],dp[i][j] = dp[i-1][j-1] + 1
    X[i] != Y[j],dp[i][j] = 0
    对于初始化,i==0或者j==0,如果X[i] == Y[j],dp[i][j] = 1;否则dp[i][j] = 0。

    #include<stdio.h>
    #include<string.h>
    
    
    void outputLCS(char * X);
    
    // 最长公共子串 Longest Common Substring 
    int maxlen;    //记录最大公共子串长度 
    int maxindex;  // 记录最大公共子串在串1的起始位置 
    void outputLCS(char * X);  // 输出LCS 
    
    // 最长公共子串 基本算法 ===================
    int comlen(char * p, char * q)
    {
        int len = 0;
        while(*p && *q && *p++ == *q++)
        {
            ++len;
        }
        return len;
    }
     
    void LCS_base(char * X, int xlen, char * Y, int ylen)
    {
        for(int i = 0; i < xlen; ++i)
        {
            for(int j = 0; j < ylen; ++j)
            {
                int len = comlen(&X[i],&Y[j]);
                if(len > maxlen)
                {
                    maxlen = len;
                    maxindex = i;
                }
            }
        }
        outputLCS(X);
    }
    
    
    // 最长公共子串 DP ======================================
    int dp[30][30];
     
    void LCS_dp(char * X, int xlen, char * Y, int ylen)
    {
        maxlen = maxindex = 0;
        for(int i = 0; i < xlen; ++i)
        {
            for(int j = 0; j < ylen; ++j)
            {
                if(X[i] == Y[j])
                {
                    if(i && j)//i>0 && j>0
                    {
                        dp[i][j] = dp[i-1][j-1] + 1;
                    }
                    if(i == 0 || j == 0)
                    {
                        dp[i][j] = 1;
                    }
                    if(dp[i][j] > maxlen)
                    {
                        maxlen = dp[i][j];
                        maxindex = i + 1 - maxlen;
                    }
                }
            }
        }
        outputLCS(X);
    }
    
    
    
    //============  common code =============================
    
    void outputLCS(char * X)
    {
        if(maxlen == 0)
        {
            printf("NULL LCS
    ");
            return;
        }
        printf("The len of LCS is %d
    ",maxlen);
     
        int i = maxindex;
        while(maxlen--)
        {
            printf("%c",X[i++]);
        }
        printf("
    ");
    }
     
    void main()
    {
        char X[] = "aaaba";
        char Y[] = "abaa";
     
        /* 基本算法 */
        LCS_base(X,strlen(X),Y,strlen(Y));
     
        /* DP算法 */
        LCS_base(X,strlen(X),Y,strlen(Y));
     
    }


  • 相关阅读:
    一个openbsd的服务器,可以使用它的公网IP~
    深入浅出C++虚函数表
    C++函数的高级特性-函数重载
    《用TCP/IP进行网际互联》读书笔记
    C++中const的作用【转】
    C++学习继承中的作用域(10)
    ping 127.0.0.1与本机的IP有什么不同
    C++多态性:虚函数的调用原理
    mysql连接字段
    常用正则表达式
  • 原文地址:https://www.cnblogs.com/sjw1357/p/3863990.html
Copyright © 2011-2022 走看看