后缀数组有什么用?
处理字符串的一大利器
感觉这东西有点玄,网上也没有什么比较简单的讲解,我弄了几天(太菜)
写个学习笔记!!
方法
1.dc3
2.倍增
由于本人太菜,只会倍增,就讲讲倍增吧
学习前提
首先大家得食用一下基数排序,可以到百度百科学习,有个大概的印象就好
一些定义
sa[i]:排名为i的后缀的起始位置
Rank[i]:从第i个位置开始的后缀的排名
y[i]:意义与sa[i]一样,基数排序过程中要用
ch[i]:字符串
c[i]:统计次数(基数排序)
sa[i],rank[i]只要我们知道一个便可以将另一个求出
比如sa[i]=k;则rank[sa[i]]=i(rank[k]=i);
倍增
简单的讲啊,倍增就是先处理长度为1的后缀的排名,再处理长度为2的后缀的排名
接着是长度为4的,然后是8......一直到长度k大于了字符串长度n;
暴力的话复杂度太高,倍增的话复杂度可以做到O(nlogn)
这样倍增有什么好处呢??
我们假定现在已经处理到长度为2^k的后缀了,(2^0,2^1,.....2^(k-1)已经处理)
那么此时的排名其实可以通过长度为2^(k-1)的后缀的排名求出的
2^k可有两个(2^(k-1))的字符串拼成
只需将这两个(2^(k-1))的字符串分别作为基数排序的一,二关键字进行排序就可以得到此轮rank,sa。
来一张经典的图加深理解