后缀数组模板(倍增法)
来源:互联网 发布:高仿买家退货淘宝介入 编辑:程序博客网 时间:2024/05/01 07:04
#include<iostream>#include<cstdio>#include<cstring>#include<string>#define maxn 200010using namespace std;char str[maxn];int sa[maxn],wx[maxn],wy[maxn],w[maxn],wv[maxn],Rank[maxn],height[maxn],s[maxn];//sa[i]表示第i大的子串的下标,Rank[i]表示子串下标i的排名,height[i]表示sa[i]与sa[i-1]的最长公共前缀//sa[i]有效范围(i>=1&&i<=n)sa[0]=n,Rank[i]有效范围(i>=0&&i<n)Rank[n]=0,height[i]有效范围(i>=1&&i<=n)height[1]=0int cmp(int *r ,int a ,int b, int j)//比较字符串是否相等{ return (r[a]==r[b])&&(r[a+j]==r[b+j]);}void da(int *r , int n , int m){ int i,j,p,*x=wx,*y=wy,*t; for(i=0;i<m;i++)//基数排序 w[i]=0; for(i=0;i<n;i++) w[x[i]=r[i]]++; for(i=1;i<m;i++) w[i]+=w[i-1]; for(i=n-1;i>=0;i--) sa[--w[x[i]]]=i; for(j=1,p=0;p<n;j*=2,m=p)//m为基数排序的参数 { 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<n;i++) wv[i]=x[y[i]]; for(i=0;i<m;i++)//第一第二关键字组合之后的基数排序 w[i]=0; for(i=0;i<n;i++) w[wv[i]]++; for(i=1;i<m;i++) w[i]+=w[i-1]; for(i=n-1;i>=0;i--) sa[--w[wv[i]]]=y[i]; for(p=1,i=1,t=x,x=y,y=t,x[sa[0]]=0;i<n;i++)//求出x[]为下一次第一关键字的顺序 x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++; }}void calheight(int * r , int n)//求height[]{ int i,k=0,j; for(i=1;i<=n;i++) { if(i==1) printf("%d",sa[i]+1); else printf(" %d",sa[i]+1); Rank[sa[i]]=i;//Rank和sa相反 } cout<<endl; for(i=0;i<n;height[Rank[i++]]=k) for(k?k--:0,j=sa[Rank[i]-1];r[i+k]==r[j+k];k++); cout<<height[1]; for(i=2;i<=n;i++) { printf(" %d",height[i]); } cout<<endl;}int main(){ while(scanf("%s",str)!=EOF) { int len=strlen(str); for(int i=0; i<len; i++)//把字符转化为整形 s[i]=str[i]; s[len]=0; da(s,len+1,128);//多了一个s[len],长度加1 calheight(s,len); } return 0;}
0 0
- 后缀数组模板(倍增法)
- 后缀数组 倍增法模板
- 后缀数组(倍增法)
- 后缀数组-倍增发(模板)
- 后缀数组 倍增算法模板
- 后缀数组倍增法
- 后缀数组(倍增)
- 后缀数组(倍增)
- SA(后缀数组)——倍增法模板
- 后缀数组二倍增模板解析
- 后缀数组倍增算法模板详解
- 后缀数组--倍增法实现
- 后缀数组之倍增法
- 后缀数组--倍增法注解
- 倍增法求后缀数组
- 后缀数组的倍增模板与DC3模板
- 后缀数组的倍增法实现
- 后缀数组 (由倍增算法构造)
- HDU 1171 Big Event in HDU(01背包)
- UVa 11489 - Integer Game (简单博弈 脑筋急转弯)
- uvalive 6396 数论 世界决赛的题
- tinyxml使用
- 模拟退火算法
- 后缀数组模板(倍增法)
- TopCoder-BadNeighbours
- Android开发————Alarm学习笔记
- c# 截取字符串两特定字符中间的字符
- thrift 编程
- [小技巧] tree显示中文
- 关于中间表
- Linux中如何将文件dump成16进制值
- 数据结构第5章例题 若矩阵Am×n中存在某个元素aij满足:aij是第i行中的最小值且是第j列中的最大值,则称该元素为矩阵A的一个鞍点。试编写一个算法,找出A中的所有鞍点。