• 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函数。

  • 相关阅读:
    Java中顺序、并行与并发
    Java设计模式之Iterator
    渗透基础流程思路丶技巧丶与总结
    阿里巴巴Java开发手册之并发处理注意事项
    Java中Thread方法启动线程
    IOCP之客户端及消息传递
    IOCP简单实现
    JAVA 递归线程池测试 ExecutorService / ForkJoinPool
    TCP与UDP的一些心得
    七.badboy检查点和参数化
  • 原文地址:https://www.cnblogs.com/ZQUACM-875180305/p/9294752.html
Copyright © 2020-2023  润新知