首页 > 学院 > 开发设计 > 正文

poj 3080 求多个串的公共字串(同poj3450)

2019-11-08 01:00:21
字体:
来源:转载
供稿:网友
////  main.cpp//  后缀数组////  Created by liuzhe on 17/2/5.//  Copyright © 2017年 my_code. All rights reserved.//#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <algorithm>using namespace std;const int inf=0x3f3f3f3f;const int MAXN=810000;int wa[MAXN],wb[MAXN],wv[MAXN],ww[MAXN];int sa[MAXN],lcp[MAXN],Rank[MAXN],rank1[MAXN];char str1[MAXN];inline bool cmp(int *r,int a,int b,int len){    return r[a]==r[b]&&r[a+len]==r[b+len];}void construct_sa(char *str,int n,int m){    int i,j,p,*x=wa,*y=wb,*t;    for(i=0;i<m;i++) ww[i]=0;    for(i=0;i<n;i++) ww[x[i]=str[i]]++;    for(i=1;i<m;i++) ww[i]+=ww[i-1];    for(i=n-1;i>=0;i--) sa[--ww[x[i]]]=i;    for(j=p=1;p<n;j<<=1,m=p){        for(p=0,i=n-j;i<n;i++)            y[p++]=i;        for(i=0;i<n;i++){            if(sa[i]>=j)                y[p++]=sa[i]-j;        }        for(i=0;i<m;i++) ww[i]=0;        for(i=0;i<n;i++) ww[wv[i]=x[y[i]]]++;        for(i=1;i<m;i++) ww[i]+=ww[i-1];        for(i=n-1;i>=0;i--) sa[--ww[wv[i]]]=y[i];        for(t=x,x=y,y=t,x[sa[0]]=0,p=i=1;i<n;i++)            x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;    }}void construct_lcp(int n,char *str){    for(int i=0;i<=n;i++) rank1[sa[i]]=i;    int h=0;    lcp[0]=0;    for(int i=0;i<n;i++){        int j=sa[rank1[i]-1];        if(h>0) h--;        for(;j+h<n&&i+h<n;h++) if(str[i+h]!=str[j+h]) break;        lcp[rank1[i]-1]=h;    }}int id[MAXN],vis[4010],pos;char str2[2010];int judge(int mid,int n,int k){    memset(vis,0,sizeof(vis));    int sum = 0;    for(int i=0;i<k;i++)    {        if(lcp[i]<mid)        {            if(sum==0)                continue;            memset(vis,0,sizeof(vis));            sum = 0;            continue;        }        if(vis[id[sa[i]]]==0)        {            sum++;            vis[id[sa[i]]] = 1;        }        if(vis[id[sa[i+1]]]==0)        {            sum++;            vis[id[sa[i+1]]] = 1;        }        if(sum==n)        {            pos = sa[i];            return 1;        }    }    return 0;}int main(){    int n,t;    cin>>t;    while(t--)    {        scanf("%d",&n);        int k=0;        memset(id,-1,sizeof(id));        memset(str1,'/n',sizeof(str1));        for(int i=0;i<n;i++)        {            scanf("%s",str2);            int len=strlen(str2);            for(int j=0;j<len;j++)            {                str1[k]=str2[j];                id[k++]=i;            }            if(i!=n-1)                str1[k++]='*';        }        construct_sa(str1,k+1,300);        construct_lcp(k,str1);        int le=0,ri=2010;        while(ri-le>1)        {            int mid=(le+ri)>>1;            if(judge(mid,n,k))                le=mid;            else                ri=mid;        }        if(le<3)            PRintf("no significant commonalities/n");        else        {            for(int i=pos,j=0;j<le;j++,i++)                printf("%c",str1[i]);            printf("/n");        }    }    return 0;}
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表