cp_library_rs/string/z.rs
1//! Z-Algorithm
2
3/// 文字列 s に対して,
4///
5/// ```text
6/// z[i] := lcp(s, s[i..])
7/// ```
8///
9/// を満たす配列 z を求める.
10///
11/// - 時間計算量: $`O(|s|)`$
12///
13/// ---
14///
15/// 参考:
16/// - <https://qiita.com/Pro_ktmr/items/16904c9570aa0953bf05>
17pub fn z_algorithm<T: PartialEq>(s: &[T]) -> Vec<usize> {
18 let n = s.len();
19 if n == 0 {
20 return vec![];
21 }
22
23 let mut z = vec![0; n];
24 z[0] = n;
25
26 let mut i = 1;
27 let mut j = 0;
28
29 while i < n {
30 while i + j < n && s[j] == s[i + j] {
31 j += 1;
32 }
33 z[i] = j;
34
35 if j == 0 {
36 i += 1;
37 continue;
38 }
39
40 let mut k = 1;
41 while k < j && k + z[k] < j {
42 z[i + k] = z[k];
43 k += 1;
44 }
45 i += k;
46 j -= k;
47 }
48
49 z
50}