• 最长公共子串


    题:给定两个字符串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));
     
    }


  • 相关阅读:
    T100——azzi600栏位问题
    E10——Sharedata 使用
    java 集合List remove 报错 ConcurrentModificationException
    java jsckson 深拷贝时 java 8 LocalDateTime 报错解决
    shell 参数定义报错 command not found
    shell 对txt文本的写入与读取
    java 实体类里浅拷贝 与 深拷贝
    Tesseract ocr java 报错JFIF APP0 must be first marker after SOI 解决
    Tesseract Java 调用其识别ocr 报错Not a JPEG file: starts with 0x89 0x50 解决
    Tesseract java 实现ocr的具体步骤 win10系统
  • 原文地址:https://www.cnblogs.com/sjw1357/p/3863990.html
Copyright © 2020-2023  润新知