@@ -61,13 +61,12 @@ impl<'a, C: Eq> Matcher<'a, C> {
61
61
///
62
62
/// ```
63
63
/// use contest_algorithms::string_proc::Matcher;
64
- /// let utf8_string = "hello";
65
- ///
66
- /// let match_from_byte_literal = Matcher::new(b"hello");
67
- ///
68
- /// let match_from_bytes = Matcher::new(utf8_string.as_bytes());
69
- ///
64
+ /// let byte_string: &[u8] = b"hello";
65
+ /// let utf8_string: &str = "hello";
70
66
/// let vec_char: Vec<char> = utf8_string.chars().collect();
67
+ ///
68
+ /// let match_from_byte_literal = Matcher::new(byte_string);
69
+ /// let match_from_utf8 = Matcher::new(utf8_string.as_bytes());
71
70
/// let match_from_chars = Matcher::new(&vec_char);
72
71
///
73
72
/// let vec_int = vec![4, -3, 1];
@@ -93,24 +92,24 @@ impl<'a, C: Eq> Matcher<'a, C> {
93
92
Self { pattern, fail }
94
93
}
95
94
96
- /// KMP algorithm, sets match_lens [i] = length of longest prefix of pattern
95
+ /// KMP algorithm, sets @return [i] = length of longest prefix of pattern
97
96
/// matching a suffix of text[0..=i].
98
- pub fn kmp_match ( & self , text : & [ C ] ) -> Vec < usize > {
99
- let mut match_lens = Vec :: with_capacity ( text. len ( ) ) ;
97
+ pub fn kmp_match ( & self , text : impl IntoIterator < Item = C > ) -> Vec < usize > {
100
98
let mut len = 0 ;
101
- for ch in text {
102
- if len == self . pattern . len ( ) {
103
- len = self . fail [ len - 1 ] ;
104
- }
105
- while len > 0 && self . pattern [ len] != * ch {
106
- len = self . fail [ len - 1 ] ;
107
- }
108
- if self . pattern [ len] == * ch {
109
- len += 1 ;
110
- }
111
- match_lens. push ( len) ;
112
- }
113
- match_lens
99
+ text. into_iter ( )
100
+ . map ( |ch| {
101
+ if len == self . pattern . len ( ) {
102
+ len = self . fail [ len - 1 ] ;
103
+ }
104
+ while len > 0 && self . pattern [ len] != ch {
105
+ len = self . fail [ len - 1 ] ;
106
+ }
107
+ if self . pattern [ len] == ch {
108
+ len += 1 ;
109
+ }
110
+ len
111
+ } )
112
+ . collect ( )
114
113
}
115
114
}
116
115
@@ -141,7 +140,7 @@ impl<C: std::hash::Hash + Eq> MultiMatcher<C> {
141
140
142
141
/// Precomputes the automaton that allows linear-time string matching.
143
142
/// If there are duplicate patterns, all but one copy will be ignored.
144
- pub fn new ( patterns : Vec < impl IntoIterator < Item = C > > ) -> Self {
143
+ pub fn new ( patterns : impl IntoIterator < Item = impl IntoIterator < Item = C > > ) -> Self {
145
144
let mut trie = Trie :: default ( ) ;
146
145
let pat_nodes: Vec < usize > = patterns. into_iter ( ) . map ( |pat| trie. insert ( pat) ) . collect ( ) ;
147
146
@@ -171,16 +170,16 @@ impl<C: std::hash::Hash + Eq> MultiMatcher<C> {
171
170
}
172
171
}
173
172
174
- /// Aho-Corasick algorithm, sets match_nodes [i] = node corresponding to
173
+ /// Aho-Corasick algorithm, sets @return [i] = node corresponding to
175
174
/// longest prefix of some pattern matching a suffix of text[0..=i].
176
- pub fn ac_match ( & self , text : & [ C ] ) -> Vec < usize > {
177
- let mut match_nodes = Vec :: with_capacity ( text. len ( ) ) ;
175
+ pub fn ac_match ( & self , text : impl IntoIterator < Item = C > ) -> Vec < usize > {
178
176
let mut node = 0 ;
179
- for ch in text {
180
- node = Self :: next ( & self . trie , & self . fail , node, & ch) ;
181
- match_nodes. push ( node) ;
182
- }
183
- match_nodes
177
+ text. into_iter ( )
178
+ . map ( |ch| {
179
+ node = Self :: next ( & self . trie , & self . fail , node, & ch) ;
180
+ node
181
+ } )
182
+ . collect ( )
184
183
}
185
184
186
185
/// For each non-empty match, returns where in the text it ends, and the index
@@ -235,9 +234,9 @@ impl SuffixArray {
235
234
}
236
235
237
236
/// Suffix array construction in O(n log n) time.
238
- pub fn new ( text : & [ u8 ] ) -> Self {
239
- let n = text. len ( ) ;
240
- let init_rank = text . iter ( ) . map ( | & ch| ch as usize ) . collect :: < Vec < _ > > ( ) ;
237
+ pub fn new ( text : impl IntoIterator < Item = u8 > ) -> Self {
238
+ let init_rank = text. into_iter ( ) . map ( |ch| ch as usize ) . collect :: < Vec < _ > > ( ) ;
239
+ let n = init_rank . len ( ) ;
241
240
let mut sfx = Self :: counting_sort ( 0 ..n, & init_rank, 256 ) ;
242
241
let mut rank = vec ! [ init_rank] ;
243
242
// Invariant at the start of every loop iteration:
@@ -291,7 +290,7 @@ impl SuffixArray {
291
290
/// # Panics
292
291
///
293
292
/// Panics if text is empty.
294
- pub fn palindromes < T : Eq > ( text : & [ T ] ) -> Vec < usize > {
293
+ pub fn palindromes ( text : & [ impl Eq ] ) -> Vec < usize > {
295
294
let mut pal = Vec :: with_capacity ( 2 * text. len ( ) - 1 ) ;
296
295
pal. push ( 1 ) ;
297
296
while pal. len ( ) < pal. capacity ( ) {
@@ -339,27 +338,21 @@ mod test {
339
338
340
339
#[ test]
341
340
fn test_kmp_matching ( ) {
342
- let text = b"banana ";
343
- let pattern = b"ana ";
341
+ let pattern = "ana ";
342
+ let text = "banana ";
344
343
345
- let matches = Matcher :: new ( pattern) . kmp_match ( text) ;
344
+ let matches = Matcher :: new ( pattern. as_bytes ( ) ) . kmp_match ( text. bytes ( ) ) ;
346
345
347
346
assert_eq ! ( matches, vec![ 0 , 1 , 2 , 3 , 2 , 3 ] ) ;
348
347
}
349
348
350
349
#[ test]
351
350
fn test_ac_matching ( ) {
352
- let text = b"banana bans, apple benefits." ;
353
- let dict = vec ! [
354
- "banana" . bytes( ) ,
355
- "benefit" . bytes( ) ,
356
- "banapple" . bytes( ) ,
357
- "ban" . bytes( ) ,
358
- "fit" . bytes( ) ,
359
- ] ;
360
-
361
- let matcher = MultiMatcher :: new ( dict) ;
362
- let match_nodes = matcher. ac_match ( text) ;
351
+ let dict = vec ! [ "banana" , "benefit" , "banapple" , "ban" , "fit" ] ;
352
+ let text = "banana bans, apple benefits." ;
353
+
354
+ let matcher = MultiMatcher :: new ( dict. iter ( ) . map ( |s| s. bytes ( ) ) ) ;
355
+ let match_nodes = matcher. ac_match ( text. bytes ( ) ) ;
363
356
let end_pos_and_id = matcher. get_end_pos_and_pat_id ( & match_nodes) ;
364
357
365
358
assert_eq ! (
@@ -370,11 +363,11 @@ mod test {
370
363
371
364
#[ test]
372
365
fn test_suffix_array ( ) {
373
- let text1 = b "bobocel";
374
- let text2 = b "banana";
366
+ let text1 = "bobocel" ;
367
+ let text2 = "banana" ;
375
368
376
- let sfx1 = SuffixArray :: new ( text1) ;
377
- let sfx2 = SuffixArray :: new ( text2) ;
369
+ let sfx1 = SuffixArray :: new ( text1. bytes ( ) ) ;
370
+ let sfx2 = SuffixArray :: new ( text2. bytes ( ) ) ;
378
371
379
372
assert_eq ! ( sfx1. sfx, vec![ 0 , 2 , 4 , 5 , 6 , 1 , 3 ] ) ;
380
373
assert_eq ! ( sfx2. sfx, vec![ 5 , 3 , 1 , 0 , 4 , 2 ] ) ;
@@ -393,9 +386,9 @@ mod test {
393
386
394
387
#[ test]
395
388
fn test_palindrome ( ) {
396
- let text = b "banana";
389
+ let text = "banana" ;
397
390
398
- let pal_len = palindromes ( text) ;
391
+ let pal_len = palindromes ( text. as_bytes ( ) ) ;
399
392
400
393
assert_eq ! ( pal_len, vec![ 1 , 0 , 1 , 0 , 3 , 0 , 5 , 0 , 3 , 0 , 1 ] ) ;
401
394
}
0 commit comments