cp_library_rs/string/
suffix_array.rs1macro_rules! cfor {
4 ($def:stmt ; $fin:expr ; $incr:stmt ;; $bl:block) => {{
5 $def
6 while $fin {
7 $bl
8 $incr
9 }
10 }}
11}
12
13pub struct SuffixArray;
15
16impl SuffixArray {
17 fn ord(rank: &[isize], i: usize, k: usize) -> (isize, isize) {
19 (rank[i], *rank.get(i + k).unwrap_or(&-1))
20 }
21
22 pub fn build(S: &str) -> Vec<usize> {
25 let N = S.len();
26 let mut rank: Vec<_> = S.chars().map(|c| c as isize).collect();
27 rank.push(-1);
29 let mut sa: Vec<_> = (0..=N).collect();
30
31 cfor! {let mut k = 1; k <= N; k *= 2;; {
32 sa.sort_by_key(|&i| Self::ord(&rank, i, k));
34 let mut tmp = vec![0; N + 1];
36 tmp[sa[0]] = 0;
37 for i in 1..=N {
38 tmp[sa[i]] = tmp[sa[i - 1]] +
39 (Self::ord(&rank, sa[i - 1], k) < Self::ord(&rank, sa[i], k)) as isize;
40 }
41 rank = tmp;
42 }}
43 sa
44 }
45}