POJ 3450 Corporate Identity (KMP,求公共子串,方法很妙)

http://blog.sina.com.cn/s/blog_74e20d8901010pwp.html
我采用的是方法三。

注意:当长度相同时,取字典序最小的。

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
/*
http://blog.sina.com.cn/s/blog_74e20d8901010pwp.html
我采用的是方法三。

注意:当长度相同时,取字典序最小的。
*/
using namespace std;
const int maxn=4005;
char str[maxn][210];
int n;
int minlen; //n个字符串中最短的长度
int id; //长度最短字符串的编号
int next[210];

void getNext(char*P){
    int k;
    int lm=strlen(P);
    next[1]=0;
    k=0;
    for(int i=1;i<lm;i++){
        while(k>0 && P[k]!=P[i])
            k=next[k];
        if(P[k]==P[i])
            k++;
        next[i+1]=k;
    }
}

int kmp(char*T,char*P){
    int k,c;
    c=0; //表示字符串P在T中能够匹配的最大长度
    int ln=strlen(T),lm=strlen(P);
    for(int i=0;i<ln;i++){
        while(k>0&&P[k]!=T[i])
            k=next[k];
        if(P[k]==T[i])
            k++;
        if(k>c)
            c=k;
        if(k==lm)
            return k;
    }
    return c;
}
int main()
{
    int l;
    while(scanf("%d",&n)!=EOF){
        if(n==0)
            break;
        minlen=1000;
        for(int i=1;i<=n;i++){
            scanf("%s",str[i]);
            l=strlen(str[i]);
            if(l<minlen){
                minlen=l;
                id=i;
            }
        }
        char tmp[210],s[210];
        int minl,maxl=0,cnt;
        //minl为枚举的后缀在其余n-1个字符串中都能匹配的长度
        //maxl为公共子串的最大长度
        char ans[210]; //所求公共子串
        for(int i=1;i<=minlen;i++){
            strncpy(tmp,str[id]+minlen-i,i);
            tmp[i]='\0';
            getNext(tmp);
            minl=i+1;
            for(int j=1;j<=n;j++){
                if(j!=id){
                    cnt=kmp(str[j],tmp);
                    minl=min(cnt,minl);
                }
            }
            if(minl>maxl){
                maxl=minl;
                strncpy(ans,tmp,minl);
                ans[minl]='\0';
            }
            //如果相等长度,则输出字典序最小的
            else if(minl==maxl){
                strncpy(s,tmp,minl);
                s[minl]='\0';
                if(strcmp(s,ans)<0)
                    strcpy(ans,s);
            }
        }
        if(maxl==0)
            printf("IDENTITY LOST\n");
        else
            printf("%s\n",ans);

    }
    return 0;
}
View Code

 

 

posted @ 2014-02-12 21:31  辰曦~文若  阅读(237)  评论(0编辑  收藏  举报