File tree 2 files changed +65
-0
lines changed
2 files changed +65
-0
lines changed Original file line number Diff line number Diff line change @@ -35,3 +35,4 @@ pub mod maximum_flow;
35
35
pub mod radix_sorts;
36
36
37
37
pub mod tries;
38
+ pub mod substring_search;
Original file line number Diff line number Diff line change
1
+ use std:: iter;
2
+
3
+ pub struct KMP < ' a > {
4
+ r : usize ,
5
+ dfa : Vec < Vec < usize > > ,
6
+ pat : & ' a str
7
+ }
8
+
9
+ impl < ' a > KMP < ' a > {
10
+ // create the DFA from a string pattern
11
+ pub fn new < ' b > ( pat : & ' b str ) -> KMP < ' b > {
12
+ let r = 256 ;
13
+ let m = pat. len ( ) ;
14
+ let dfa = iter:: repeat ( iter:: repeat ( 0 ) . take ( m) . collect :: < Vec < usize > > ( ) )
15
+ . take ( r) . collect ( ) ;
16
+
17
+ let mut ret = KMP {
18
+ r : r,
19
+ dfa : dfa,
20
+ pat : pat
21
+ } ;
22
+ ret. build_dfa ( ) ;
23
+ ret
24
+ }
25
+
26
+ fn build_dfa ( & mut self ) {
27
+ let m = self . pat . len ( ) ;
28
+ let r = self . r ;
29
+ self . dfa [ self . pat . char_at ( 0 ) as usize ] [ 0 ] = 1 ;
30
+ let mut x = 0 ;
31
+ for j in 1 .. m {
32
+ for c in 0 .. r {
33
+ self . dfa [ c] [ j] = self . dfa [ c] [ x] ; // copy mismatch cases
34
+ }
35
+ self . dfa [ self . pat . char_at ( j) as usize ] [ j] = j+1 ; // set match case
36
+ x = self . dfa [ self . pat . char_at ( j) as usize ] [ x] ;
37
+ }
38
+ }
39
+
40
+ pub fn search ( & self , txt : & str ) -> Option < usize > {
41
+ let m = self . pat . len ( ) ;
42
+ let n = txt. len ( ) ;
43
+ let mut i = 0 ;
44
+ let mut j = 0 ;
45
+ while i < n && j < m {
46
+ j = self . dfa [ txt. char_at ( i) as usize ] [ j] ;
47
+ i += 1 ;
48
+ }
49
+ if j == m {
50
+ Some ( i-m)
51
+ } else {
52
+ None
53
+ }
54
+ }
55
+ }
56
+
57
+
58
+ #[ test]
59
+ fn test_kmp ( ) {
60
+ let pat = "abracadabra" ;
61
+ let text = "abacadabrabracabracadabrabrabracad" ;
62
+ let kmp = KMP :: new ( pat) ;
63
+ assert ! ( kmp. search( text) . map_or( false , |pos| text[ pos..] . starts_with( pat) ) ) ;
64
+ }
You can’t perform that action at this time.
0 commit comments