Suffix array是解决string search问题的一个工具,它是一个字串所有后缀的排序。
线性时间的构建算法主要有Kärkkäinen-Sanders(1)、Ko-Aluru(2)、KSP三种,其中KSP算法使用了类似suffix
tree的构建方式,Kärkkäinen-Sanders算法时间复杂度的递推式为
按照3的注记,借鉴4对LMS substring递归排序使用的方法, 对原始的Ko-Aluru算法进行改动以简化内存使用和提升性能。 我的实现在字串和suffix array外仅使用两个数组:计数排序使用的桶和一个表示L/S类型的数组, 反映了Ko-Aluru算法能达到和5同等的精简内存占用。
Ka-Aluru suffix array construction algorithm
规定
令字符集为
并结合以上两种分类定义:
对于
根据
根据6的induced sorting,只要确定了
下面考虑如何递归求出
定义L-substring为夹在相邻两个L(-)类型字符间的子串。
定义S-substring为夹在相邻两个S(+)类型字符间的子串。 定义一个L-substring
对于两个长度不同的L-substring
先用桶排序求出所有L类型字符的大小,使用一次induced
sorting根据L计算S,这样便得到了所有形如
实现技巧
整个实现分为几个阶段,仍然设
- 计算
数组,需要使用 - 使用两次induced sorting计算L-substring的大小,需要使用
- 根据L-substring构建新字串递归计算子suffix array
- 根据子suffix array计算
部分的suffix array - 使用induced sorting根据
部分的suffix array得到整体suffix array
其中第2、3步需要特别注意,使用了很多技巧来节省空间占用。比如新串的长度不大于sa[]
数组的空间,递归调用后对sa[]
进行原地操作进行位置变换。
注意到
多数文献都在
为L,因为把哨兵字符看作字典序最小。 - 根据S-substring计算L-substring的induced sorting过程提前把
放入桶中。否则因为它是最后一个字符,无法被放入桶中,当该字符的桶包含两个或更多元素时可能会导致它的位置被覆盖而出错。 - 计算新字符集时,需要注意比较过程中到达边界的情况。
Ko-Aluru算法的伪代码如下:
1 | fn ka S sa n |
实现
C++:
1 |
|
OCaml:
1 | module KoAluru = struct |
参考文献
Juha Kärkkäinen and Peter Sanders. “Simple Linear Work Suffix Array Construction”. English. In: Automata, Languages and Programming. Ed. by JosC.M. Baeten et al. Vol. 2719. Lecture Notes in Computer Science. Springer Berlin Heidelberg, 2003, pp. 943–955. isbn: 978-3-540-40493-4. doi: 10.1007/3-540-45061-0_73. url: http://dx.doi.org/10.1007/3-540-45061-0_73.↩︎
Pang Ko and Srinivas Aluru. “Space efficient linear time construction of suffix arrays”. In: Journal of Discrete Algorithms. Springer, 2003, pp. 200–210.↩︎
YANG Zhe. Suffix Array Construction: KA's algorithm and Induced Sorting, which is faster? 2012. url: http://yangzhe1990.wordpress.com/2012/11/04/ka-and-induced-sortingwhich-is-faster/.↩︎
Ge Nong, Sen Zhang, and Wai Hong Chan. “Two Efficient Algorithms for Linear Time Suffix Array Construction”. In: IEEE Transactions on Computers 60.10 (2011), pp. 1471–1484. issn: 0018-9340. doi: http://doi.ieeecomputersociety.org/10.1109/TC.2010.188.↩︎
Ge Nong, Sen Zhang, and Wai Hong Chan. “Two Efficient Algorithms for Linear Time Suffix Array Construction”. In: IEEE Transactions on Computers 60.10 (2011), pp. 1471–1484. issn: 0018-9340. doi: http://doi.ieeecomputersociety.org/10.1109/TC.2010.188.↩︎
Pang Ko and Srinivas Aluru. “Space efficient linear time construction of suffix arrays”. In: Journal of Discrete Algorithms. Springer, 2003, pp. 200–210.↩︎
Pang Ko and Srinivas Aluru. “Space efficient linear time construction of suffix arrays”. In: Journal of Discrete Algorithms. Springer, 2003, pp. 200–210.↩︎
Ge Nong, Sen Zhang, and Wai Hong Chan. “Two Efficient Algorithms for Linear Time Suffix Array Construction”. In: IEEE Transactions on Computers 60.10 (2011), pp. 1471–1484. issn: 0018-9340. doi: http://doi.ieeecomputersociety.org/10.1109/TC.2010.188.↩︎