Skip to content

Commit c4c30cd

Browse files
author
Caitlin Gao
committed
feat(geektime_algo): add 34 string kmp_search
1 parent 31b0908 commit c4c30cd

File tree

1 file changed

+58
-0
lines changed

1 file changed

+58
-0
lines changed

rust/34_string/kmp.rs

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
fn kmp_search(primary: &str, pattern: &str) -> Vec<i32> {
2+
if primary.is_empty() || pattern.is_empty() || pattern.len() > primary.len() { return vec![0]; }
3+
4+
let primary_chars: Vec<char> = primary.chars().collect();
5+
let pattern_chars: Vec<char> = pattern.chars().collect();
6+
let max_match_lengths = get_failure_function(pattern);
7+
let mut count = 0;
8+
let m = pattern.len();
9+
let mut positions = vec![];
10+
11+
for i in 0..primary.len() {
12+
while count > 0 && pattern_chars[count as usize] != primary_chars[i] {
13+
count = max_match_lengths[(count-1) as usize];
14+
}
15+
16+
if pattern_chars[count as usize] == primary_chars[i] {
17+
count += 1;
18+
}
19+
20+
if count as usize == m {
21+
positions.push((i - m + 1) as i32);
22+
count = max_match_lengths[(count-1) as usize];
23+
}
24+
}
25+
26+
positions
27+
}
28+
29+
fn get_failure_function(pattern: &str) -> Vec<i32> {
30+
let m = pattern.len();
31+
let mut max_match_lengths: Vec<i32> = vec![0; m];
32+
let mut max_length: i32 = 0;
33+
let pattern_chars: Vec<char> = pattern.chars().collect();
34+
35+
for i in 1..m {
36+
while max_length > 0 && pattern_chars[max_length as usize] != pattern_chars[i] {
37+
max_length = max_match_lengths[(max_length-1) as usize];
38+
}
39+
40+
if pattern_chars[i] == pattern_chars[max_length as usize] {
41+
max_length += 1;
42+
}
43+
44+
max_match_lengths[i] = max_length;
45+
}
46+
47+
max_match_lengths
48+
}
49+
50+
fn main() {
51+
let primary1 = "abbaabbaaba";
52+
let pattern1 = "abbaaba";
53+
println!("{:?}", kmp_search(primary1, pattern1)); // 4
54+
55+
let primary = "abc abcdab abcdabcdabde";
56+
let pattern = "bcdabd";
57+
println!("{:?}", kmp_search(primary, pattern)); // 16
58+
}

0 commit comments

Comments
 (0)