后缀数组是解字符串问题的一个工具,后缀数组的构建复杂度为O(NLogN),在后缀数组的基础上进行模板匹配的复杂度为O(MLogN)。下面的JAVA代码适用于只包含0-255之间字符的字符串的后缀数组的构建。
参考文献:《算法竞赛入门经典训练指南》P221,刘汝佳,陈锋
package ProgrammingContest;
public class ArrayOfSuffix {
public static int[] calculateSA(String str) {
int n = str.length();
int m = 256;
int maxn = (n>m)?n:m;
int[] x = new int[n];
int[] y = new int[n];
int[] c = new int[maxn];
int[] sa = new int[n];
//基数排序
for ( int i=0; i<m; i++ ) c[i] = 0;
for ( int i=0; i<n; i++ ) c[x[i]=str.charAt(i)]++;
for ( int i=1; i<m; i++ ) c[i] += c[i-1];
for ( int i=n-1; i>=0; i-- ) sa[--c[x[i]]]=i;
//Manber & Myers 倍增算法
for ( int k=1; k<=n; k <<= 1 ) {
//利用sa按第二关键字排序,原x后缀变成x-k后缀的第二关键字
int p = 0;
for ( int i=n-k; i<n