feat(geektime_algo): add 34 string kmp_search
This commit is contained in:
parent
31b0908077
commit
c4c30cda9e
58
rust/34_string/kmp.rs
Normal file
58
rust/34_string/kmp.rs
Normal file
@ -0,0 +1,58 @@
|
||||
fn kmp_search(primary: &str, pattern: &str) -> Vec<i32> {
|
||||
if primary.is_empty() || pattern.is_empty() || pattern.len() > primary.len() { return vec![0]; }
|
||||
|
||||
let primary_chars: Vec<char> = primary.chars().collect();
|
||||
let pattern_chars: Vec<char> = pattern.chars().collect();
|
||||
let max_match_lengths = get_failure_function(pattern);
|
||||
let mut count = 0;
|
||||
let m = pattern.len();
|
||||
let mut positions = vec![];
|
||||
|
||||
for i in 0..primary.len() {
|
||||
while count > 0 && pattern_chars[count as usize] != primary_chars[i] {
|
||||
count = max_match_lengths[(count-1) as usize];
|
||||
}
|
||||
|
||||
if pattern_chars[count as usize] == primary_chars[i] {
|
||||
count += 1;
|
||||
}
|
||||
|
||||
if count as usize == m {
|
||||
positions.push((i - m + 1) as i32);
|
||||
count = max_match_lengths[(count-1) as usize];
|
||||
}
|
||||
}
|
||||
|
||||
positions
|
||||
}
|
||||
|
||||
fn get_failure_function(pattern: &str) -> Vec<i32> {
|
||||
let m = pattern.len();
|
||||
let mut max_match_lengths: Vec<i32> = vec![0; m];
|
||||
let mut max_length: i32 = 0;
|
||||
let pattern_chars: Vec<char> = pattern.chars().collect();
|
||||
|
||||
for i in 1..m {
|
||||
while max_length > 0 && pattern_chars[max_length as usize] != pattern_chars[i] {
|
||||
max_length = max_match_lengths[(max_length-1) as usize];
|
||||
}
|
||||
|
||||
if pattern_chars[i] == pattern_chars[max_length as usize] {
|
||||
max_length += 1;
|
||||
}
|
||||
|
||||
max_match_lengths[i] = max_length;
|
||||
}
|
||||
|
||||
max_match_lengths
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let primary1 = "abbaabbaaba";
|
||||
let pattern1 = "abbaaba";
|
||||
println!("{:?}", kmp_search(primary1, pattern1)); // 4
|
||||
|
||||
let primary = "abc abcdab abcdabcdabde";
|
||||
let pattern = "bcdabd";
|
||||
println!("{:?}", kmp_search(primary, pattern)); // 16
|
||||
}
|
Loading…
Reference in New Issue
Block a user