1use super::super::traits::push_pop;
4
5use std::fmt::Debug;
6use std::ops::Range;
7
8use push_pop::{PopBack, PushBack};
9
10#[derive(Clone, Debug, Eq, PartialEq)]
60pub struct KmpSearcher<T: Eq> {
61 pat: Vec<T>,
62 fail: Vec<usize>,
63 fail1: Vec<usize>,
64}
65
66impl<T: Eq> From<Vec<T>> for KmpSearcher<T> {
67 fn from(pat: Vec<T>) -> Self {
68 let len = pat.len();
69 let fail1 = vec![1_usize.wrapping_neg(); len + 1];
70 let fail = fail1.clone();
71 let mut self_ = Self { pat, fail1, fail };
72 for i in 0..self_.pat.len() {
73 let (f, f1) = self_.calc_fail(i);
74 self_.fail1[i + 1] = f1;
75 self_.fail[i + 1] = f;
76 }
77 self_
78 }
79}
80
81impl<T: Eq> KmpSearcher<T> {
82 fn calc_fail(&self, i: usize) -> (usize, usize) {
83 let pat_i = &self.pat[i];
84 let mut j = self.fail1[i];
85 while j < self.pat.len() && pat_i != &self.pat[j] {
86 j = self.fail[j];
87 }
88 j = j.wrapping_add(1);
89 match self.pat.get(i + 1) {
90 Some(pat_ni) if pat_ni == &self.pat[j] => (self.fail[j], j),
91 _ => (j, j),
92 }
93 }
94
95 pub fn occurrences<'a>(&'a self, s: &'a [T]) -> Occurrences<'a, T> {
96 Occurrences {
97 text_index: 0,
98 pat_index: 0,
99 kmp: &self,
100 text: s,
101 }
102 }
103}
104
105pub struct Occurrences<'a, T: Eq> {
106 text_index: usize,
107 pat_index: usize,
108 kmp: &'a KmpSearcher<T>,
109 text: &'a [T],
110}
111
112impl<T: Eq> Iterator for Occurrences<'_, T> {
113 type Item = Range<usize>;
114 fn next(&mut self) -> Option<Self::Item> {
115 let text = self.text;
116 let pat = &self.kmp.pat;
117
118 if pat.is_empty() {
119 return if self.text_index < text.len() {
120 let i = self.text_index;
121 self.text_index += 1;
122 Some(i..i)
123 } else {
124 None
125 };
126 }
127
128 let mut j = self.pat_index;
129 for (i, c) in text[self.text_index..].iter().enumerate() {
130 let i = i + self.text_index;
131 while j < pat.len() && &pat[j] != c {
132 j = self.kmp.fail[j];
133 }
134 j = j.wrapping_add(1);
135 if j == pat.len() {
136 let e = i + 1;
137 let res = e - pat.len()..e;
138 self.text_index = e;
139 self.pat_index = self.kmp.fail[j];
140 return Some(res);
141 }
142 }
143 self.text_index = text.len();
144 None
145 }
146}
147
148impl<T: Eq> PushBack for KmpSearcher<T> {
149 type Input = T;
150 fn push_back(&mut self, x: T) {
151 let len = self.pat.len();
152 if len > 0 {
153 let j = self.fail1[len];
154 if &self.pat[j] == &x {
155 let tmp = self.fail[j];
156 self.fail[len] = tmp;
157 }
158 }
159 self.pat.push(x);
160 let (f, f1) = self.calc_fail(len);
161 self.fail1.push(f1);
162 self.fail.push(f);
163 }
164}
165
166impl<T: Eq> PopBack for KmpSearcher<T> {
167 type Output = usize;
168 fn pop_back(&mut self) -> Option<usize> {
169 if self.pat.is_empty() {
170 None
171 } else {
172 self.pat.pop();
173 self.fail1.pop();
174 let res = self.fail.pop();
175 *self.fail.last_mut().unwrap() = *self.fail1.last().unwrap();
176 res
177 }
178 }
179}