Rust中是否存在C++ ranges::contains_subrange的等价实现?
Rust中是否存在C++ ranges::contains_subrange的等价实现?
嘿,好问题!在Rust标准库中,目前没有直接对应C++ ranges::contains_subrange的内置函数,不过我们有几种简单灵活的方式来实现同样的功能,适配不同的集合类型~
一、针对连续内存集合(Vec、数组、字符串等):用windows快速实现
像Vec<T>、数组[T; N]、&str这类基于连续内存的集合,我们可以利用Rust切片的windows方法来快速实现子序列检查——这个方法会生成原切片所有指定长度的连续子切片,我们只需要判断其中是否有和目标子序列匹配的即可。
// 通用的子序列检查函数,适用于所有能转成切片的集合 fn contains_subrange<T: PartialEq>(haystack: &[T], needle: &[T]) -> bool { // 遵循惯例:空的子序列默认匹配任何序列 if needle.is_empty() { return true; } // 子序列比原序列长,直接返回不匹配 if needle.len() > haystack.len() { return false; } // 遍历所有等长子切片,检查是否有匹配项 haystack.windows(needle.len()).any(|window| window == needle) } // 用法示例 fn main() { // 对Vec的检查 let nums = vec![1, 2, 3, 4, 5]; let target_sub = vec![2, 3]; let wrong_sub = vec![2, 4]; assert!(contains_subrange(&nums, &target_sub)); assert!(!contains_subrange(&nums, &wrong_sub)); // 对字符串的检查(也可以直接用str::contains,更高效) let sentence = "the quick brown fox"; let sub_str = "quick brown"; assert!(contains_subrange(sentence.as_bytes(), sub_str.as_bytes())); assert!(sentence.contains(sub_str)); // 哦对了,字符串本身有专门的contains方法,优先用这个! }
二、针对非连续内存集合(LinkedList等):迭代器实现
如果是LinkedList这种非连续内存的集合,没法用windows方法,那我们可以用双迭代器的方式实现通用的子序列检查:
use std::iter::Peekable; // 基于迭代器的通用子序列检查,适配所有可迭代类型 fn contains_subrange_iter<H, N>(mut haystack: H, mut needle: N) -> bool where H: Iterator, N: Iterator + Clone, H::Item: PartialEq<N::Item>, { let mut needle_peek = needle.clone().peekable(); // 空序列默认匹配 if needle_peek.peek().is_none() { return true; } loop { match (haystack.next(), needle_peek.peek()) { // 当前元素匹配,移动子序列迭代器指针 (Some(hay_item), Some(needle_item)) if hay_item == *needle_item => { needle_peek.next(); // 子序列已经遍历完,说明匹配成功 if needle_peek.peek().is_none() { return true; } } // 当前元素不匹配,重置子序列迭代器,从原序列下一个元素开始检查 (Some(_), Some(_)) => { needle_peek = needle.clone().peekable(); } // 原序列遍历完了,子序列还没结束,匹配失败 (None, Some(_)) => return false, // 其他情况(比如子序列已经遍历完),返回最终结果 _ => return needle_peek.peek().is_none(), } } } // 用法示例 fn main() { let list = std::collections::LinkedList::from([10, 20, 30, 40]); let sub_list = std::collections::LinkedList::from([20, 30]); assert!(contains_subrange_iter(list.iter(), sub_list.iter())); }
三、进阶:高性能场景用第三方库
如果要处理非常大的数据集,或者需要更高效的匹配算法(比如Boyer-Moore、Aho-Corasick),可以直接用crates.io上的成熟库:
memchr:针对字节序列的高性能匹配,底层做了很多硬件优化;aho-corasick:支持多模式子序列匹配,适合同时检查多个子序列的场景。
内容来源于stack exchange
相关产品推荐
相关产品推荐

