The Manber-Myers Algorithm is an algorithm that finds the lexicographical order of the suffixes of a string of length in time and space.
Tip
This problem can also be solved by Selection Sort in time and space.
Tip
This problem can also be solved by Insertion Sort in time and space.
Tip
This problem can also be solved by Bubble Sort in time and space.
Tip
This problem can also be solved by Merge Sort in time and space.
Tip
This problem can also be solved by Heapsort in time and space.
Tip
This problem can also be solved by Quicksort in time and space.
Algorithm
- Apply an appropriate sorting algorithm (e.g., Merge Sort, Heapsort, Quicksort) to find the lexicographical order of .
- For , let . Apply Radix Sort to find the lexicographical order of by taking the lexicographical order of as the primary key and the lexicographical order of as the secondary key.
This algorithm solves the problem in time and space.
std::vector<int> manber_myers(int n, const std::string &s) {
auto sa = std::ranges::to<std::vector>(std::views::iota(0, n));
std::ranges::sort(sa, {}, [&](int i) -> char {
return s[i];
});
std::vector<int> rk(n);
rk[sa[0]] = 0;
for (int i = 1; i < n; i++) {
rk[sa[i]] = rk[sa[i - 1]] + (s[sa[i]] != s[sa[i - 1]]);
}
for (int k = 1; k < n; k *= 2) {
auto o = std::ranges::to<std::vector>(std::views::iota(n - k, n));
for (int i : sa) {
if (i >= k) {
o.push_back(i - k);
}
}
std::vector cnt(rk[sa[n - 1]] + 1, 0);
for (int i = 0; i < n; i++) {
cnt[rk[i]]++;
}
std::exclusive_scan(cnt.begin(), cnt.end(), cnt.begin(), 0);
for (int i : o) {
sa[cnt[rk[i]]++] = i;
}
std::vector<int> nrk(n);
nrk[sa[0]] = 0;
for (int i = 1; i < n; i++) {
nrk[sa[i]] = nrk[sa[i - 1]] + (rk[sa[i]] != rk[sa[i - 1]] || sa[i - 1] + k == n || rk[sa[i] + k] != rk[sa[i - 1] + k]);
}
std::swap(rk, nrk);
}
return sa;
}