1.后缀i:字符串从第i位到最后一位的字串,如’abcd’的 后缀3 为 ‘cd’
2.suffix[i]:表示后缀i。对于字符串’ABABCDDD’有
3.sa[i]:(对这些后缀排序后)排名第i的后缀排序前的排名
4.rank[i]:第i个后缀排序后的排名。
5.height[i]:(排序后)第i-1个后缀和(排序后)第i个后缀的最大公共前缀,如 ‘DDD’ 和 ‘DD’,最大公共前缀长度即为 2。
1.若rank[i] = sa[j]则sa[i] = rank[j],rank[sa[i]] = sa[rank[i]] = i
2.如果rank[j]
3.
h
e
i
g
h
t
[
r
a
n
k
[
i
]
]
≥
h
e
i
g
h
t
[
r
a
n
k
[
i
−
1
]
]
−
1
height[rank[i]]≥height[rank[i−1]]−1
height[rank[i]]≥height[rank[i−1]]−1
1.略
2.假如suffix[i]和suffix[j],有rank[i]
对于rank[i] +1 < rank[j]的情况,中间字符串的大小介于它俩之间,第sa(i,j)位及之前肯定都是相等的,sa(i,j)+1位的转变肯定是在其中某两个字符串上发生的,所以也必然成立。
3.若排序后suffix[k-1]刚好排在suffix[i-1]前面,且它们的最小前缀为height[rank[i-1]]且不为0。
此时必定满足suffix[k]刚好排在suffix[i]前面,且它们的最小公共前缀 height[rank[i]] 正好为 height[rank[i-1]]-1
如果height[rank[i-1]] = 0,显然也成立。
有一种类似于基数排序的方法。
以aaabcda为例子
①先把
n
位分成
n
个字符,放在一个数组里,求出每个字母的排名
①先把n位分成n个字符,放在一个数组里,求出每个字母的排名
①先把n位分成n个字符,放在一个数组里,求出每个字母的排名
②设
i
为
0
,把每一个字符,加上后面的第
2
i
−
1
个字符形成一个小字符串,用排名数字代替字母后,再次排名,得到每一个子串的排名
② 设 i 为 0,把每一个字符,加上后面的第 2^{i-1} 个字符形成一个小字符串,用排名数字代替字母后,再次排名,得到每一个子串的排名
②设i为0,把每一个字符,加上后面的第2i−1个字符形成一个小字符串,用排名数字代替字母后,再次排名,得到每一个子串的排名
③令
i
+
1
,把字符串看成一个新的字符,继续执行②,直到
1
+
2
i
−
1
>
n
,即可得到
n
个后缀子串的排名,即
r
a
n
k
和
s
a
,实际求取的时候全程用数字代替字符,免去字符长度带来的复杂度
③令i+1,把字符串看成一个新的字符,继续执行②,直到1+2^{i-1}\gt n,即可得到n个后缀子串的排名,即rank和sa,实际求取的时候全程用数字代替字符,免去字符长度带来的复杂度
③令i+1,把字符串看成一个新的字符,继续执行②,直到1+2i−1>n,即可得到n个后缀子串的排名,即rank和sa,实际求取的时候全程用数字代替字符,免去字符长度带来的复杂度
每次取后面第
2
i
−
1
个字符,为的就是能够拼出完整且正确的后缀
每次取后面第2^{i-1}个字符,为的就是能够拼出完整且正确的后缀
每次取后面第2i−1个字符,为的就是能够拼出完整且正确的后缀
在这里插入代码片