这个实现比较粗糙,速度慢,内存需求也大. struct SFX { int idx; int key1, key2; }; int operator < (const SFX& x, const SFX& y) { return x.key1 < y.key1 || x.key1 == y.key1 && x.key2 < y.key2; } inline void BuildRank(SFX* sfx, int* rank, int len, int init_rank) { int last_rank = init_rank; rank[sfx[0].idx] = init_rank; for (int i = 1; i != len; ++i) { if (sfx[i-1] < sfx[i]) ++last_rank; rank[sfx[i].idx] = last_rank; } } template<typename EleType> inline void BuildSA(EleType* text, int* SA, int* rank, int len) { const int CharSet = 128; const int count_len = max(CharSet, len) +10; SFX * sfx = new SFX[len], * sfx_temp = new SFX[len]; int * count_temp = new int[count_len]; memset(count_temp, 0, sizeof(count_temp[0]) * count_len); for (int i = 0; i != len; ++i) ++count_temp[text[i]]; for (int i = 1; i != CharSet; ++i) count_temp[i] += count_temp[i-1]; for (int i = 0; i < len; ++i) { int pos = --count_temp[text[i]]; sfx[pos].idx = i; sfx[pos].key2 = 0; sfx[pos].key1 = text[i]; } for (int wid = 1; wid <len; wid <<= 1) { BuildRank(sfx, rank, len, 1); for (int i = 0; i != len; ++i) { sfx[i].idx = i; sfx[i].key1 = rank[i]; sfx[i].key2 = i + wid < len ? rank[i+wid] : 0; } memset(count_temp, 0, sizeof(count_temp[0]) * count_len); for (int i = 0; i < len; ++i) ++count_temp[sfx[i].key2]; for (int i = 1; i <= len; ++i) count_temp[i] += count_temp[i-1]; for (int i = len-1; i >= 0; --i) sfx_temp[--count_temp[sfx[i].key2]] = sfx[i]; memset(count_temp, 0, sizeof(count_temp[0]) * count_len); for (int i = 0; i < len; ++i) ++count_temp[sfx_temp[i].key1]; for (int i = 1; i <= len; ++i) count_temp[i] += count_temp[i-1]; for (int i = len-1; i >= 0; --i) sfx[--count_temp[sfx_temp[i].key1]] = sfx_temp[i]; //sort(sfx, sfx+len); } for (int i = 0; i != len; ++i) SA[i] = sfx[i].idx, rank[SA[i]] = i; delete[] count_temp;delete[] sfx_temp;delete[] sfx; } template<typename EleType> int GetLCP(EleType* a, EleType* b) { int l=0; while(*a && *b && *a==*b) { l++; a++; b++; } return l; } template<typename EleType> void GetLCP(EleType* text, int *SA, int * rank, int len, int* lcp) { lcp[0] = 0; if (rank[0]) { lcp[rank[0]] = GetLCP(text, text + SA[rank[0]-1]); } for (int i = 1; i < len; i++) { if ( !rank[i] ) continue; if (lcp[rank[i-1]] <= 1) { lcp[rank[i]] = GetLCP(text+i, text+SA[ rank[i]-1 ]); } else { int L = lcp[ rank[i - 1] ] - 1; lcp[rank[i]] = L+GetLCP(text+i+L, text+SA[rank[i]-1]+L); } } }