forked from t3nsor/codebook
-
Notifications
You must be signed in to change notification settings - Fork 0
/
suffix-array.cpp
59 lines (53 loc) · 1.95 KB
/
suffix-array.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
// Suffix array construction in O(L log^2 L) time. Routine for
// computing the length of the longest common prefix of any two
// suffixes in O(log L) time.
//
// INPUT: string s
//
// OUTPUT: array suffix[] such that suffix[i] = index (from 0 to L-1)
// of substring s[i...L-1] in the list of sorted suffixes.
// That is, if we take the inverse of the permutation suffix[],
// we get the actual suffix array.
struct SuffixArray {
const int L;
string s;
vector<vector<int> > P;
vector<pair<pair<int,int>,int> > M;
SuffixArray(const string &s) : L(s.length()), s(s), P(1, vector<int>(L, 0)), M(L) {
for (int i = 0; i < L; i++) P[0][i] = L==1 ? i : int(s[i]);
for (int skip = 1, level = 1; skip < L; skip *= 2, level++) {
P.push_back(vector<int>(L, 0));
for (int i = 0; i < L; i++)
M[i] = make_pair(make_pair(P[level-1][i], i + skip < L ? P[level-1][i + skip] : -1000), i);
sort(M.begin(), M.end());
for (int i = 0; i < L; i++)
P[level][M[i].second] = (i > 0 && M[i].first == M[i-1].first) ? P[level][M[i-1].second] : i;
}
}
vector<int> GetSuffixArray() { return P.back(); }
// returns the length of the longest common prefix of s[i...L-1] and s[j...L-1]
int LongestCommonPrefix(int i, int j) {
int len = 0;
if (i == j) return L - i;
for (int k = P.size() - 1; k >= 0 && i < L && j < L; k--) {
if (P[k][i] == P[k][j]) {
i += 1 << k;
j += 1 << k;
len += 1 << k;
}
}
return len;
}
};
int main() {
// bobocel is the 0'th suffix
// obocel is the 5'th suffix
// bocel is the 1'st suffix
SuffixArray suffix("bobocel");
vector<int> v = suffix.GetSuffixArray();
// Expected output: 0 5 1 6 2 3 4
// 2
for (int i = 0; i < v.size(); i++) cout << v[i] << " ";
cout << endl;
cout << suffix.LongestCommonPrefix(0, 2) << endl;
}