competitive/string/z_algorithm.rs
1#[derive(Clone, Debug)]
2pub struct Zarray {
3 z: Vec<usize>,
4}
5impl Zarray {
6 pub fn new<T: Eq>(s: &[T]) -> Self {
7 let n = s.len();
8 let mut z = vec![0; n];
9 z[0] = n;
10 let (mut i, mut j) = (1, 0);
11 while i < n {
12 while i + j < n && s[j] == s[i + j] {
13 j += 1;
14 }
15 z[i] = j;
16 if j == 0 {
17 i += 1;
18 continue;
19 }
20 let mut k = 1;
21 while i + k < n && k + z[k] < j {
22 z[i + k] = z[k];
23 k += 1;
24 }
25 i += k;
26 j -= k;
27 }
28 Self { z }
29 }
30 pub fn search<T: Eq>(s: &[T], pat: &[T], sep: T) -> Vec<usize> {
31 let mut res = vec![];
32 let mut t = vec![];
33 t.extend(pat);
34 t.push(&sep);
35 t.extend(s);
36 let zarray = Self::new(&t);
37 for i in 0..t.len() {
38 if zarray[i] == pat.len() {
39 res.push(i - pat.len() - 1);
40 }
41 }
42 res
43 }
44}
45impl std::ops::Index<usize> for Zarray {
46 type Output = usize;
47 fn index(&self, index: usize) -> &usize {
48 &self.z[index]
49 }
50}