-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSuffixArray.cpp
More file actions
131 lines (122 loc) · 3.03 KB
/
Copy pathSuffixArray.cpp
File metadata and controls
131 lines (122 loc) · 3.03 KB
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/**
* Author: Kevin Li
* Lang: C++
* Description: Suffix Array Implementation, also LCP array in O(n) using Kasai algorithm
*/
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
#define ALPH 52
#define MAXC 256
#define MAXN 200100
struct SA {
string s;
int n;
int *ar, *art, *sa, *sat;
int *freq;
int limit;
int *ps;
int *lcp;
int *plcp;
SA () {}
SA (string _s) : s(_s) {
s += '$';
n = (int)s.length();
ar = new int[n];
art = new int[n];
sa = new int[n];
sat = new int[n];
limit = max(MAXC,n);
freq = new int[limit];
}
void rsort(int j) {
for (int i = 0; i < limit; i++) freq[i] = 0;
for (int i = 0; i < n; i++) {
if (i + j < n) {
freq[ar[i+j]]++;
} else {
freq[0]++;
}
}
int s = 0;
for (int i = 0; i < limit; i++) {
int temp = freq[i]; freq[i] = s; s += temp;
}
for (int i = 0; i < n; i++) {
if (sa[i] + j < n) {
sat[freq[ar[sa[i]+j]]] = sa[i];
freq[ar[sa[i]+j]]++;
} else {
sat[freq[0]] = sa[i];
freq[0]++;
}
}
for (int i = 0; i < n; i++) sa[i] = sat[i];
}
void driver() {
for (int i = 0; i < n; i++) {
ar[i] = s[i];
sa[i] = i;
art[i] = sat[i] = 0;
}
for (int i = 1; i < n; i *= 2) {
rsort(i); rsort(0);
art[sa[0]] = 0; int rank = 0;
for (int j = 1; j < n; j++) {
if (ar[sa[j]] == ar[sa[j-1]] && ar[sa[j]+i] == ar[sa[j-1]+i]) {
art[sa[j]] = rank;
} else {
rank++; art[sa[j]] = rank;
}
}
for (int j = 0; j < n; j++) ar[j] = art[j];
if (ar[sa[n-1]] == n-1) break;
}
}
void lcpk() {
ps = new int[n];
lcp = new int[n];
plcp = new int[n];
ps[sa[0]] = -1;
for (int i = 1; i < n; i++) {
ps[sa[i]] = sa[i-1];
}
int match = 0;
for (int i = 0; i < n; i++) {
if (ps[i] == -1) {
plcp[i] = 0;
} else {
while (s[i+match] == s[ps[i]+match]) {
match++;
}
plcp[i] = match;
match = max(match-1,0);
}
}
for (int i = 0; i < n; i++) {
lcp[i] = plcp[sa[i]];
}
}
void print() {
for (int i = 1; i <= n-1; i++) {
cout << sa[i] << " ";
}
cout << endl;
}
void printlcp() {
for (int i = 2; i <= n-1; i++) {
cout << lcp[i] << " ";
}
cout << endl;
}
};
string s;
int main() {
cin >> s;
SA suffixarray = SA(s);
suffixarray.driver();
suffixarray.lcpk();
suffixarray.print();
suffixarray.printlcp();
}