diff --git a/rust/find-the-index-of-the-first-occurrence-in-a-string/Cargo.toml b/rust/find-the-index-of-the-first-occurrence-in-a-string/Cargo.toml new file mode 100644 index 0000000..74be928 --- /dev/null +++ b/rust/find-the-index-of-the-first-occurrence-in-a-string/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "find-the-index-of-the-first-occurrence-in-a-string" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/rust/find-the-index-of-the-first-occurrence-in-a-string/src/main.rs b/rust/find-the-index-of-the-first-occurrence-in-a-string/src/main.rs new file mode 100644 index 0000000..4de399c --- /dev/null +++ b/rust/find-the-index-of-the-first-occurrence-in-a-string/src/main.rs @@ -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, + 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 { + let mut table: Vec = 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!"); +}