15 #ifndef PAAL_SUFFIX_ARRAY_HPP
16 #define PAAL_SUFFIX_ARRAY_HPP
20 #include <boost/range/algorithm/fill.hpp>
21 #include <boost/range/algorithm/max_element.hpp>
22 #include <boost/range/numeric.hpp>
45 template <
typename Letter>
46 inline bool leq(Letter a1,
int a2, Letter b1,
48 return (a1 < b1 || (a1 == b1 && a2 <= b2));
62 template <
typename Letter>
63 inline bool leq(Letter a1, Letter a2,
int a3, Letter b1, Letter b2,
int b3) {
64 return (a1 < b1 || (a1 == b1 &&
leq(a2, a3, b2, b3)));
69 template <
typename Letter>
70 radix_pass(
int max_letter,
const std::vector<Letter> & text) {
71 if (max_letter == 0) {
72 max_letter = *boost::max_element(text);
74 c.resize(max_letter + 2);
78 template <
typename Iterator>
79 void operator()(std::vector<int>
const &sortFrom,
80 std::vector<int> &sortTo, Iterator r,
int n) {
83 ++c[r[sortFrom[i]] + 1];
86 boost::partial_sum(c, c.begin());
89 sortTo[c[r[sortFrom[i]]]++] = sortFrom[i];
109 template <
typename Letter>
112 int n = text.size() - 3;
114 int n0 = (n + 2) / 3, n1 = (n + 1) / 3, n2 = n / 3, n02 = n0 + n2;
115 text.resize(text.size() + 3);
116 std::vector<int> text12;
117 std::vector<int> SA12;
118 std::vector<int> text0;
119 std::vector<int> SA0;
123 for (
auto i :
irange(n + (n0 - n1))) {
129 SA12.resize(n02 + 3);
130 text12.resize(n02 + 3);
132 radix(text12, SA12, text.begin() + 2, n02);
133 radix(SA12, text12, text.begin() + 1, n02);
134 radix(text12, SA12, text.begin(), n02);
138 Letter c0 = Letter{}, c1 = Letter{}, c2 = Letter{};
139 for (
auto i :
irange(n02)) {
140 if (text[SA12[i]] != c0 || text[SA12[i] + 1] != c1 ||
141 text[SA12[i] + 2] != c2 || name == 0) {
144 c1 = text[SA12[i] + 1];
145 c2 = text[SA12[i] + 2];
147 if (SA12[i] % 3 == 1) {
148 text12[SA12[i] / 3] = name;
150 text12[SA12[i] / 3 + n0] = name;
156 suffix_array<int>(text12, SA12, name);
158 for (
auto i :
irange(n02)) {
159 text12[SA12[i]] = i + 1;
162 for (
auto i :
irange(n02)) {
163 SA12[text12[i] - 1] = i;
168 for (
auto i :
irange(n02)) {
170 text0.push_back(3 * SA12[i]);
173 radix(text0, SA0, text.begin(), n0);
174 auto GetI = [&](
int t)->
int {
175 return SA12[t] < n0 ? SA12[t] * 3 + 1 : (SA12[t] - n0) * 3 + 2;
179 auto p = SA0.begin();
181 for (
auto k = SA.begin(); k < SA.begin() + n; k++) {
185 ?
leq(text[i], text12[SA12[t] + n0], text[j], text12[j / 3])
186 :
leq(text[i], text[i + 1], text12[SA12[t] - n0 + 1], text[j],
187 text[j + 1], text12[j / 3 + n0])) {
194 k = std::copy(p, SA0.end(), k);
201 if (p == SA0.end()) {
202 for (k++; t < n02; t++, k++) {
226 template <
typename Letter>
228 Letter max_letter = 0) {
229 text.resize(text.size() + 3);
231 text.resize(text.size() - 3);
235 #endif // PAAL_SUFFIX_ARRAY_HPP
bool leq(Letter a1, int a2, Letter b1, int b2)
return true if pair (a1,a2) is smaller than pair (b1,b2) in lexicographic order and false otherwise ...
auto irange(T begin, T end)
irange
void suffix_array(std::vector< Letter > &text, std::vector< int > &SA, Letter max_letter=0)
detail
void suffix_array(std::vector< Letter > &text, std::vector< int > &SA, Letter max_letter)
require text[n]=text[n+1]=text[n+2]=0, n>=2 fill suffix_array suffix_array[i] contains the starting po...