1
1
//! String processing algorithms.
2
2
3
3
/// Data structure for Knuth-Morris-Pratt string matching against a pattern.
4
- pub struct Matcher < ' a > {
4
+ pub struct Matcher < ' a , T > {
5
5
/// The string pattern to search for.
6
- pub pattern : & ' a [ u8 ] ,
6
+ pub pattern : & ' a [ T ] ,
7
7
/// KMP match failure automaton. fail[i] is the length of the longest
8
8
/// proper prefix-suffix of pattern[0...i].
9
9
pub fail : Vec < usize > ,
10
10
}
11
11
12
- impl < ' a > Matcher < ' a > {
12
+ impl < ' a , T : Eq > Matcher < ' a , T > {
13
13
/// Precomputes the automaton that allows linear-time string matching.
14
14
///
15
+ /// # Example
16
+ ///
17
+ /// ```
18
+ /// use contest_algorithms::string_proc::Matcher;
19
+ /// let utf8_string = "hello";
20
+ ///
21
+ /// let match_from_byte_literal = Matcher::new(b"hello");
22
+ ///
23
+ /// let match_from_bytes = Matcher::new(utf8_string.as_bytes());
24
+ ///
25
+ /// let vec_char: Vec<char> = utf8_string.chars().collect();
26
+ /// let match_from_chars = Matcher::new(&vec_char);
27
+ ///
28
+ /// let vec_int = vec![4, -3, 1];
29
+ /// let match_from_ints = Matcher::new(&vec_int);
30
+ /// ```
31
+ ///
15
32
/// # Panics
16
33
///
17
34
/// Panics if pattern is empty.
18
- pub fn new ( pattern : & ' a [ u8 ] ) -> Self {
35
+ pub fn new ( pattern : & ' a [ T ] ) -> Self {
19
36
let mut fail = Vec :: with_capacity ( pattern. len ( ) ) ;
20
37
fail. push ( 0 ) ;
21
38
let mut len = 0 ;
22
- for & ch in & pattern[ 1 ..] {
23
- while len > 0 && pattern[ len] != ch {
39
+ for ch in & pattern[ 1 ..] {
40
+ while len > 0 && pattern[ len] != * ch {
24
41
len = fail[ len - 1 ] ;
25
42
}
26
- if pattern[ len] == ch {
43
+ if pattern[ len] == * ch {
27
44
len += 1 ;
28
45
}
29
46
fail. push ( len) ;
@@ -33,17 +50,17 @@ impl<'a> Matcher<'a> {
33
50
34
51
/// KMP algorithm, sets matches[i] = length of longest prefix of pattern
35
52
/// matching a suffix of text[0...i].
36
- pub fn kmp_match ( & self , text : & [ u8 ] ) -> Vec < usize > {
53
+ pub fn kmp_match ( & self , text : & [ T ] ) -> Vec < usize > {
37
54
let mut matches = Vec :: with_capacity ( text. len ( ) ) ;
38
55
let mut len = 0 ;
39
- for & ch in text {
56
+ for ch in text {
40
57
if len == self . pattern . len ( ) {
41
58
len = self . fail [ len - 1 ] ;
42
59
}
43
- while len > 0 && self . pattern [ len] != ch {
60
+ while len > 0 && self . pattern [ len] != * ch {
44
61
len = self . fail [ len - 1 ] ;
45
62
}
46
- if self . pattern [ len] == ch {
63
+ if self . pattern [ len] == * ch {
47
64
len += 1 ;
48
65
}
49
66
matches. push ( len) ;
@@ -151,7 +168,7 @@ impl<K: std::hash::Hash + Eq + Default> Trie<K> {
151
168
node. count += 1 ;
152
169
153
170
for ch in word {
154
- node = { node } . branches . entry ( ch) . or_insert_with ( Default :: default ) ;
171
+ node = { node } . branches . entry ( ch) . or_default ( ) ;
155
172
node. count += 1 ;
156
173
}
157
174
}
@@ -177,7 +194,7 @@ impl<K: std::hash::Hash + Eq + Default> Trie<K> {
177
194
/// # Panics
178
195
///
179
196
/// Panics if text is empty.
180
- pub fn palindromes ( text : & [ u8 ] ) -> Vec < usize > {
197
+ pub fn palindromes < T : Eq > ( text : & [ T ] ) -> Vec < usize > {
181
198
let mut pal = Vec :: with_capacity ( 2 * text. len ( ) - 1 ) ; // only mutable var!
182
199
pal. push ( 1 ) ;
183
200
while pal. len ( ) < pal. capacity ( ) {
@@ -210,8 +227,8 @@ mod test {
210
227
211
228
#[ test]
212
229
fn test_kmp ( ) {
213
- let text = "banana" . as_bytes ( ) ;
214
- let pattern = "ana" . as_bytes ( ) ;
230
+ let text = b "banana";
231
+ let pattern = b "ana";
215
232
216
233
let matches = Matcher :: new ( pattern) . kmp_match ( text) ;
217
234
@@ -220,8 +237,8 @@ mod test {
220
237
221
238
#[ test]
222
239
fn test_suffix_array ( ) {
223
- let text1 = "bobocel" . as_bytes ( ) ;
224
- let text2 = "banana" . as_bytes ( ) ;
240
+ let text1 = b "bobocel";
241
+ let text2 = b "banana";
225
242
226
243
let sfx1 = SuffixArray :: new ( text1) ;
227
244
let sfx2 = SuffixArray :: new ( text2) ;
@@ -261,7 +278,7 @@ mod test {
261
278
262
279
#[ test]
263
280
fn test_palindrome ( ) {
264
- let text = "banana" . as_bytes ( ) ;
281
+ let text = b "banana";
265
282
266
283
let pal_len = palindromes ( text) ;
267
284
0 commit comments