公共最长(连续)子串

   思路很简单,动态规划就行了,设dp[i][j]为a串的0-i,b串的0-j的最长公共后缀长度。那么状态转移方程就是dp[i][j]=a[i]==b[i]?dp[i-1][j-1]:0

因为在i j为0时可能会出现dp[-1][-1]的情况,所以把dp数组后推一位,且dp数组会用到的最多就是dp[i-1][j-1],所以可以优化一下空间,把它变成一维数组从后往前dp,代码如下:

#include <bits/stdc++.h>
using namespace std;
char a[10000007],b[10000007];
int dp[10000007];
int main()
{
    while(1)
    {
        scanf("%s%s",a,b);
        int acd=strlen(a);//计算a和b字符串长度 
        int bcd=strlen(b);
        int maxn=0,jl;//maxn用来记录最长后缀,jl记录maxn出现时公共字符串位置。 
        memset(dp,0,(sizeof (int))*(bcd+1));//把dp置0,初始化。 
        for(int i=0;i<acd;i++)
        {
            for(int j=bcd-1;j>=0;j--)
            {
                dp[j+1]=a[i]==b[j]?dp[j]+1:0;//核心代码,状态转移。 
                if(maxn<dp[j+1])
                {
                    maxn=dp[j+1];//更新maxn与jl 
                    jl=i-maxn+1;
                }
            }
        }
        printf("%d\n",maxn);//输出 
        for(int i=jl;i<jl+maxn;i++)
        {
            printf("%c",a[i]);
        }
        printf("\n");
    }
}