POJ - 3080——Blue Jeans (KMP)

点击打开题目链接

题意:给m个长度不超过60的字符串,输出这些字符串共同的最长公共子串。(多组输入)当然,题目给的数据m<=10&&字符串长度不超过60,所以可以直接暴力做。这里只讲用KMP来写的解法。

题解:枚举第一个串的所有子串,然后用KMP算法去匹配这个子串和所有其它串看是否在其它串中都出现过,如果都出现过那肯定就是大家共同的公共子串。为了简单我们可以直接从最长的往短的遍历,这样第一个符合要求的一定就是最长的子串直接结束输出就行了。做法特别简单相当于是KMP的模板题。

附上代码: 

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
string s[15];
int next[100];
void get_next(string a, int next[])
{
    int lena =a.size();
    next[0] = -1;
    int k = -1;
    int j = 0;
    while (j < lena - 1)
    {
        if(k == -1 || a[j] == a[k])//a[k]表示前缀,a[j]表示后缀
        {
            ++j;
            ++k;
            next[j]=k;
        }
        else
        {
            k = next[k];
        }
    }
}
int kmp(string a,string b)//a模式串,b匹配串
{
    int lena=a.size();
    int lenb=b.size();
    int i=0;
    int j=0;
    while(i<lena&&j<lenb)
    {
        if(j==-1||a[i]==b[j])
        {
            i++;
            j++;
        }
        else
        {
            j=next[j];
        }
    }
    if(j==lenb)
            return i-j;
        return -1;
}
int main()
{
    int t,n;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        string ans="";//一定要定义在里面否则会wa
        for(int i=1;i<=n;i++)
            cin>>s[i];
        int len1=s[1].size();
        int l;
        int bo,boo=0;
        for(l=len1;l>=3;l--)//枚举字符串长度
        {
            bo=0;
            for(int i=0;i<=len1-l;i++)//枚举起点终点
        {
            memset(next,0,sizeof(next));
            string ss=s[1].substr(i,l);//记住这种操作,把一个字符串的一部分单独截出来
            get_next(ss,next);
            int flag=0;
            for(int j=2;j<=n;j++)
            {
                if(kmp(s[j],ss)==-1)
                {
                    flag=1;
                    break;
                }
            }
            if(flag==0)
            {
                bo=1;
               int len2=ans.size();
               int len3=ss.size();
               if(len2<len3)
                  ans=ss;
                else if(len2==len3)
                    ans=min(ans,ss);
            }
        }
        if(bo==1)
        {
            boo=1;
            cout<<ans<<endl;
            break;
        }
    }
        if(boo==0)
            printf("no significant commonalities\n");
    }
    return 0;
}
 

猜你喜欢

转载自blog.csdn.net/wookaikaiko/article/details/81087449