我的模板是用的大白上面的,但是比较坑的是,我发现例如aaaa求出来的sa数组并不正确,而这一道题中用哪个版也是过不了,找了很久发现在重新更新x数组的时候是需要判断是否越界的,改过来就对了,有点。。。。
思路很简单,够着sa数组和h数组然后暴力统计
#include<cstdio>
#include<cstring>
#include<iostream>
#define maxn 3010
using namespace std;
int n,t1[maxn],t2[maxn],sa[maxn],c[maxn],h[maxn],rank[maxn];
char s[maxn];
bool cmp(int* y,int a,int b,int k){
int aa=a+k>=n?-1:y[a+k];
int bb=b+k>=n?-1:y[b+k];
return y[a]==y[b]&&aa==bb;
}
void make(int n,int m){
int *x=t1,*y=t2,i,p=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){
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]]=cmp(y,sa[i],sa[i-1],k)? p-1 : p++;
if(p>=n)break;m=p;
}
}
void get_h(){
for(int i=0;i<n;i++)rank[sa[i]]=i;
for(int k=0,i=0,j;i<n;i++){
if(k)k--;
if(!rank[i])continue;
j=sa[rank[i]-1];
while(s[i+k]==s[j+k])k++;
h[rank[i]]=k;
}
}
void solve(){
int k=0,l;
for(int i=0;i<n;i++){
for(int j=h[i]+1;j+sa[i]-1<n;j++){
l=i;
while(h[l+1]>=j)l++;
if(l>i)printf("%d\n",l-i+1);
}
}
}
int main(){
scanf("%d%s",&n,s);
make(n,129);
get_h();
solve();
return 0;
}

本文详细介绍了字符串处理中的SA(Suffix Array)算法实现,并通过一个具体案例分享了调试经验。文章首先展示了完整的SA算法代码,随后针对实践中遇到的边界条件问题进行了深入分析,最后给出了如何利用SA数组和高度(height)数组进行模式匹配的具体方法。
902

被折叠的 条评论
为什么被折叠?



