博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
后缀数组 SA
阅读量:6098 次
发布时间:2019-06-20

本文共 1249 字,大约阅读时间需要 4 分钟。

后缀数组。

\(LCP(i,j)\)\(suffix(sa[i])\)\(suffix(sa[j])\)的最长公共前缀
\[LCP(i,j)=min(LCP(k,k-1)),i<=k<=j\]
\(height[i]\)表示\(LCP(i,i-1)\)
\(h[i]\)表示\(heigth[rank[i]]\)
\[h[i]>=h[i-1]-1\]

/*求sa数组,注意两个基数排序时循环要倒着。记得初始化m。m和n不要写混。*/void get_sa(){    for(int i=1;i<=n;i++) ++c[x[i]=s[i]];    for(int i=2;i<=m;i++) c[i]+=c[i-1];    for(int i=n;i;i--) sa[c[x[i]]--]=i;    for(int k=1;k<=n;k<<=1){        int p=0;        for(int i=n-k+1;i<=n;i++) y[++p]=i;        for(int i=1;i<=n;i++) if(sa[i]>k) y[++p]=sa[i]-k;  //y记录的是按照后半段排序的前半段位置        for(int i=1;i<=m;i++) c[i]=0;        for(int i=1;i<=n;i++) ++c[x[i]];        for(int i=2;i<=m;i++) c[i]+=c[i-1];        for(int i=n;i>=1;i--) sa[c[x[y[i]]]--]=y[i];        swap(x,y);        x[sa[1]]=1,p=1;        for(int i=2;i<=n;i++)            x[sa[i]]=(y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k])?p:++p;        if(p==n) break;        m=p;    }}/*求heigth数组,大概就是与排名-1的那个后缀从上次的k-1位置开始比较。*/void get_ht(){    int k=0;    for(int i=1;i<=n;i++) rk[sa[i]]=i;    for(int i=1;i<=n;i++){        if(k) k--;  //h[i]>=h[i-1]-1        if(rk[i]==1) continue;          int j=sa[rk[i]-1];        while(j+k<=n&&i+k<=n&&s[i+k]==s[j+k]) k++;        ht[rk[i]]=k;    }}

应用

:参见国家集训队论文

转载于:https://www.cnblogs.com/lsq647vsejgfb/p/9338591.html

你可能感兴趣的文章
关于裸婚,没事F5刷豆瓣是不够的!
查看>>
【FJOI2015】金币换位问题
查看>>
HighChar
查看>>
window上安装pymysql
查看>>
控件调用函数
查看>>
activity的启动模式
查看>>
Android主线程、子线程通信(Thread+handler)
查看>>
gitlab配置邮箱
查看>>
Win10桌面奔溃怎么办?雨林木风Win10奔溃解决方法教程
查看>>
mysql Inoodb 内核
查看>>
Redis 基础
查看>>
UITextField的returnkey点击事件
查看>>
特殊字体引用
查看>>
owlcar 用法心得 自定义导航
查看>>
数据结构 学习笔记03——栈与队列
查看>>
DB2 OLAP函数的使用(转)
查看>>
数学之美系列二十 -- 自然语言处理的教父 马库斯
查看>>
Android实现自定义位置无标题Dialog
查看>>
面试总结
查看>>
Chrome浏览器播放HTML5音频没声音的解决方案
查看>>