首页 > 编程语言 > 详细

后缀数组suffix array

时间:2019-08-26 16:49:33      阅读:96      评论:0      收藏:0      [点我收藏+]

自用模板:

技术分享图片
#include <iostream>
#include <string.h>
using namespace std;
const int MAX_N=210000;
char s[MAX_N];
int sa[MAX_N],t[MAX_N],t2[MAX_N],c[MAX_N],n;
void build_sa(int m)
{
    int i,*x=t,*y=t2;
    for(i=0;i<m;i++)c[i]=0;
    for(i=0;i<n;i++)c[x[i]=s[i]]++;
    for(i=1;i<m;i++)c[i]+=c[i-1];
    for(i=n-1;i>=0;i--)sa[--c[x[i]]]=i;
    for(int k=1;k<=n;k<<=1)
    {
        int p=0;
        for(i=n-k;i<n;i++)y[p++]=i;
        for(i=0;i<n;i++)if(sa[i]>=k)y[p++]=sa[i]-k;
        for(i=0;i<m;i++)c[i]=0;
        for(i=0;i<n;i++)c[x[y[i]]]++;
        for(i=1;i<m;i++)c[i]+=c[i-1];
        for(i=n-1;i>=0;i--)sa[--c[x[y[i]]]]=y[i];
        swap(x,y);
        p=1;
        x[sa[0]]=0;
        for(i=1;i<n;i++)x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++;
        if(p>=n)break;
        m=p;
    }
}
int m;
int cmp_suffix(char* patter,int p)
{
    return strncmp(patter,s+sa[p],m);
}
int find(char* P)
{
    m=strlen(P);
    if(cmp_suffix(P,0)<0)return -1;
    if(cmp_suffix(P,n-1)>0)return -1;
    int l=0,r=n;
    while(l<r)
    {
        int mid=(l+r)>>1;
        int res=cmp_suffix(P,mid);
        if(!res)
        {
            return sa[mid];
        }
        if(res<0){r=mid;}
        else{l=mid+1;}
    }
    return -1;
}

int Rank[MAX_N],h[MAX_N];
void get_h()
{
    int i,j,k=0;
    for(i=0;i<n;i++)Rank[sa[i]]=i;
    for(i=0;i<n;i++)
    {
        if(k)k--;
        if(Rank[i])
        {
            j=sa[Rank[i]-1];
            while(s[i+k]==s[j+k])k++;
            h[Rank[i]]=k;
        }
    }
}

int main() {
    char ss[MAX_N];
    cin>>s;
    n=strlen(s);
    build_sa(131);
    get_h();
    while(cin>>ss)
    {
        cout<<find(ss)<<endl;
    }
    return 0;
}
View Code

 

 

可重叠最长重复子串

不可重叠最长重复子串

最长k次重复子串

不同字串个数

后缀数组suffix array

原文:https://www.cnblogs.com/myrtle/p/11413391.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!