Implement the Knuth-Morris-Pratt algorithmw

This commit is contained in:
Samuel Ortion 2025-03-04 18:54:47 +01:00
parent 6f12b214ee
commit e76ab13277
Signed by: sortion
GPG Key ID: 9B02406F8C4FB765
2 changed files with 95 additions and 0 deletions

View File

@ -0,0 +1,6 @@
[package]
name = "find-the-index-of-the-first-occurrence-in-a-string"
version = "0.1.0"
edition = "2021"
[dependencies]

View File

@ -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!");
}