Implement the Knuth-Morris-Pratt algorithmw
This commit is contained in:
parent
6f12b214ee
commit
e76ab13277
|
@ -0,0 +1,6 @@
|
|||
[package]
|
||||
name = "find-the-index-of-the-first-occurrence-in-a-string"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
|
@ -0,0 +1,89 @@
|
|||
//! Find the Index of the First Occurrence in a String
|
||||
//!
|
||||
//! Use the Knuth-Morris-Pratt algorithm
|
||||
//!
|
||||
//! $\mathcal{O}(|P| + |T|)$ time complexity
|
||||
//! where $P$ is the pattern and $T$ is the text searched
|
||||
//!
|
||||
|
||||
struct Solution;
|
||||
|
||||
impl Solution {
|
||||
|
||||
pub fn kmp_search(prefix_table: &Vec<usize>,
|
||||
pattern: &String,
|
||||
text: &String) -> i32 {
|
||||
let mut i: usize = 0;
|
||||
let mut j: usize = 0;
|
||||
while i < text.len() {
|
||||
if text.chars().nth(i) == pattern.chars().nth(j) {
|
||||
i += 1;
|
||||
j += 1;
|
||||
if j == pattern.len() {
|
||||
return i as i32 - j as i32;
|
||||
}
|
||||
} else {
|
||||
if j != 0 {
|
||||
j = prefix_table[j - 1];
|
||||
} else {
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
pub fn kmp_prefix(pattern: &String) -> Vec<usize> {
|
||||
let mut table: Vec<usize> = vec![0; pattern.len()];
|
||||
|
||||
table[0] = 0;
|
||||
let mut i = 1;
|
||||
let mut len = 0;
|
||||
while i < pattern.len() {
|
||||
if pattern.chars().nth(i) == pattern.chars().nth(len) {
|
||||
len += 1;
|
||||
table[i] = len;
|
||||
i += 1;
|
||||
} else {
|
||||
if len != 0 {
|
||||
len = table[len - 1];
|
||||
} else {
|
||||
table[i] = 0;
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
table
|
||||
}
|
||||
|
||||
pub fn str_str(haystack: String, needle: String) -> i32 {
|
||||
let prefix = Self::kmp_prefix(&needle);
|
||||
Self::kmp_search(&prefix, &needle, &haystack)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_1() {
|
||||
let haystack = "sadbutsad".to_string();
|
||||
let needle = "sad".to_string();
|
||||
let position = Solution::str_str(haystack, needle);
|
||||
assert_eq!(position, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_2() {
|
||||
let haystack = "leetcode".to_string();
|
||||
let needle = "leeto".to_string();
|
||||
let position = Solution::str_str(haystack, needle);
|
||||
assert_eq!(position, -1);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
}
|
Loading…
Reference in New Issue