hdu 1238

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1238

题意:找出给出所有字符串中相同的最长子串。可以反向查找。

有两种做法:

1、利用stl的string,直接进行暴力。

2、用扩展kmp,直接找ext数组。

#include<cstdio>
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
string str[106];

int main()
{
    int T;
    cin >> T;
    while(T--){
        int n;
        cin >> n;
        int len=202,under;
        for(int i=1;i<=n;i++){
            cin >> str[i];
            if(len>str[i].size()){
                len=str[i].size();
                under=i;
            }
        }
        int ans=0;
        for(int i=len;i>0;i--){
            for(int j=0;j<len-i+1;j++){
                string s1,s2;
                int flag=0;
                s1=str[under].substr(j,i);
                s2=s1;
                reverse(s2.begin(),s2.end());
                for(int k=1;k<=n;k++){
                    if(str[k].find(s1)==string::npos&&str[k].find(s2)==string::npos){
                        flag=1;
                        break;
                    }
                }
                if(!flag){
                    if(ans<s1.size()) ans=s1.size();
                }
            }
            if(ans!=0) break;
        }
        printf("%d
",ans);
    }
    return 0;
}

poj 3080有用到过substr分割子串。现在在用一个reverse取反子串。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
const int maxn=505;
int nxt[105][maxn],ext[105][maxn];
char s[105][maxn];
int len[105],ans[maxn];

void exkmp(char s[],char t[],int lens,int lent,int c){
    int i,j,p,l,k;
    nxt[c][0]=lent;j=0;
    while(j+1<lent&&t[j]==t[j+1]) j++;
    nxt[c][1]=j;
    k=1;
    for(i=2;i<lent;i++){
        if(i+nxt[c][i-k]<nxt[c][k]+k) nxt[c][i]=nxt[c][i-k];
        else{
            j=max(0,nxt[c][k]+k-i);
            while(i+j<lent&&t[i+j]==t[j]) j++;
            nxt[c][i]=j;
            k=i;
        }
    }

    j=0;
    while(j<lens&&j<lent&&s[j]==t[j]) j++;
    ext[c][0]=j; k=0;
    for(i=1;i<lens;i++){
        if(nxt[c][i-k]+i<ext[c][k]+k) ext[c][i]=nxt[c][i-k];
        else{
            j=max(0,ext[c][k]+k-i);
            while(i+j<lens&&j<lent&&s[i+j]==t[j]) j++;
            ext[c][i]=j;
            k=i;
        }
    }
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--){
        memset( ans, 0x3f, sizeof ans);
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%s",s[i]);
        for(int i=1;i<=n;i++) len[i]=strlen(s[i]);
        s[1][len[1]]='#';
        for(int i=1;i<=len[1];i++)
            s[1][len[1]+i]=s[1][len[1]-i];
        s[1][len[1]+len[1]+1]=0;
        len[1]=strlen(s[1]);
        int maxx=0;
        for(int i=0;i<len[1];i++){
            for(int j=2;j<=n;j++){
                int cnt=0;
                exkmp(s[j],s[1]+i,len[j],len[1]-i,j);
                for(int k=0;k<len[j];k++){
                    if(ext[j][k]>cnt) cnt=ext[j][k];
                }
                if(cnt<ans[i]) ans[i]=cnt;
            }
            if(ans[i]>maxx) maxx=ans[i];
        }
        printf("%d
",maxx);
    }
    return 0;
}

这里就用扩展kmp直接找ext函数。

原文地址:https://www.cnblogs.com/ZQUACM-875180305/p/9294752.html