use crate::*;
pub fn slice_find<T: PartialEq>(haystack: &[T], needle: &[T]) -> Option<usize> {
let haystack_len = haystack.len();
let needle_len = needle.len();
if needle_len == 0 {
return Some(0); }
if needle_len > haystack_len {
return None; }
if needle_len == 1 {
return haystack.iter().position(|c| { c == &needle[0] });
}
if needle_len == haystack_len {
if haystack == needle {
return Some(0);
} else {
return None;
}
}
let mut lps = Vec::with_capacity(needle_len);
lps.push(0);
for item in needle.iter() {
let mut j = lps.last().copied().unwrap();
while j > 0 && item != &needle[j] {
j = lps[j - 1];
}
if item == &needle[j] {
j += 1;
}
lps.push(j);
}
let mut needle_pos = 0;
for (haystack_pos, haystack_item) in haystack.iter().enumerate() {
while needle_pos > 0 && haystack_item != &needle[needle_pos] {
needle_pos = lps[needle_pos - 1];
}
if haystack_item == &needle[needle_pos] {
needle_pos += 1;
if needle_pos == needle_len {
return Some(haystack_pos - (needle_pos - 1));
}
}
}
None
}
pub fn slice_contains<T: PartialEq>(haystack: &[T], needle: &[T]) -> bool {
slice_find(haystack, needle).is_some()
}