码迷,mamicode.com
首页 > 编程语言 > 详细

后缀数组

时间:2020-01-29 21:49:16      阅读:81      评论:0      收藏:0      [点我收藏+]

标签:for   后缀   位置   基数排序   har   代码   eof   code   scan   

后缀数组

  1. 后缀,就是从字符串中的一个字符开始直到结束的字串;而后缀数组则能求出字符串中所有后缀的排名。

  2. 介绍即将登场的数组们:sa[i]记录的是排名为i的后缀是从第几个字符开始的;Rank[i]记录的是从第i个字符开始的后缀排名第几;c[]用于基数排序;

3.代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int N=1000005;
int n,na,Rank[N],sa[N],tmp[N],c[N];
char s[N];

 void make_sa()
{
    int j,len;
    na=max(n,256);
    memset(c,0,sizeof(c));
    for (int i=0; i<n; i++) c[Rank[i]=s[i]&0xff]++;
    for (int i=0; i<na; i++) c[i]+=c[i-1];
    for (int i=0; i<n; i++) sa[--c[Rank[i]]]=i;//初始化Rank,c,sa
    for (len=1; len<n; len<<=1)
    {
        for (int i=0; i<n; i++)//i为排名
        {
            j=sa[i]-len;
            if (j<0) j+=n;
            tmp[c[Rank[j]]++]=j;//tmp相当于sa
        }
        sa[tmp[c[0]=0]]=j=0;//sa暂时相当于Rank
        for (int i=1; i<n; i++)//i为上一轮排名
        {
            if (Rank[tmp[i]]!=Rank[tmp[i-1]]||Rank[tmp[i]+len]!=Rank[tmp[i-1]+len]) c[++j]=i;
            sa[tmp[i]]=j;//j为当前排名
        }
        memcpy(Rank,sa,sizeof(Rank)); memcpy(sa,tmp,sizeof(sa));
        if (j>=n-1) break;//优化,排名无重复则已完成排序
    }
}

 int main()
{
    scanf("%s",s); s[strlen(s)]='$';
    n=strlen(s);
    make_sa();
    for (int i=1; i<n; i++) printf("%d ",sa[i]+1); printf("\n");
    return 0;
}

LCP

后缀的排名已经完成,那么有什么用呢?LCP(最长公共前缀)就出现了。

1.H[i]数组表示排名为i的后缀与其他后缀的最长公共前缀的长度。

2.想到既然所有后缀都已排名,那么相邻的后缀相似度最高,可以得到第i个后缀与其他后缀的最长公共前缀即为其与第i-1个的最长公共前缀。

void lcp()
{
    int j,k=0;
    for (int i=0; i<n; i++) Rank[sa[i]]=i;//初始化
    for (int i=0; i<n; i++)//枚举后缀的开始位置
    {
        if (k) k--;
        j=sa[Rank[i]-1];//排名为第i-1个的后缀的开始位置
        while (s[i+k]==s[j+k]) k++;//枚举最长长度
        H[Rank[i]]=k;
    }
}

后缀数组

标签:for   后缀   位置   基数排序   har   代码   eof   code   scan   

原文地址:https://www.cnblogs.com/lyxzhz/p/12241384.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!