Vector Rust是否包含直接检查一个向量是否为“a”的方法;“子字符串”;另一个?
可以使用Vector Rust是否包含直接检查一个向量是否为“a”的方法;“子字符串”;另一个?,vector,rust,Vector,Rust,可以使用contains搜索模式的String执行此操作,但是Vec::contains用于单个元素 我能做到这一点的唯一方法是直接实现某种子字符串函数,但我希望有一种内置的方法 let vec1 = vec![1, 2, 3, 4, 5]; let vec2 = vec![2, 3]; // vec2 IS a substring of vec1 let vec3 = vec![1, 5]; // vec3 is NOT a substring of vec3 fn is_subvec(ma
contains
搜索模式的String
执行此操作,但是Vec::contains
用于单个元素
我能做到这一点的唯一方法是直接实现某种子字符串函数,但我希望有一种内置的方法
let vec1 = vec![1, 2, 3, 4, 5];
let vec2 = vec![2, 3]; // vec2 IS a substring of vec1
let vec3 = vec![1, 5]; // vec3 is NOT a substring of vec3
fn is_subvec(mainvec: &Vec<i32>, subvec: &Vec<i32>) -> bool {
if subvec.len() == 0 { return true; }
if mainvec.len() == 0 { return false; }
'outer: for i in 0..mainvec.len() {
for j in 0..subvec.len() {
if mainvec[i+j] != subvec[j] {
continue 'outer;
}
}
return true;
}
return false;
}
println!("should be true: {}", is_subvec(&vec1, &vec2));
println!("should be false: {}", is_subvec(&vec1, &vec3));
让vec1=vec![1, 2, 3, 4, 5];
让vec2=vec![2, 3]; // vec2是vec1的子字符串
让vec3=vec![1, 5]; // vec3不是vec3的子字符串
fn是_subvec(mainvec:&Vec,subvec:&Vec)->bool{
如果subvec.len()==0{返回true;}
如果mainvec.len()==0{返回false;}
'外部:对于0..mainvec.len()中的i{
对于0..subvec.len()中的j{
如果mainvec[i+j]!=subvec[j]{
继续"走出去",;
}
}
返回true;
}
返回false;
}
普林顿!(“应该是真的:{}”,is_subvec(&vec1,&vec2));
普林顿!(“应为false:{}”,is_subvec(&vec1,&vec3));
我已经看到了,但这是专门针对
u8
的,我希望无论Vec
中的类型如何都适用。据我所知,标准库中没有函数或方法来检查一个切片是否是另一个切片的子切片
我们可以将您的算法推广并简化为():
值得注意的是,这些算法并不是最快的算法,因为它们的最坏情况复杂性为O(n^2)
,但它们适用于所有t:PartialEq
。可以使用诸如的算法来加快速度,但是对于小输入O(n^2)
可能由于常数因素而更好
我们可以通过将一种特质与专业化结合使用(这需要每晚一次)来改善这种情况:
#![专题(专门化)]
酒馆{
fn有_部分(&self,rhs:&self)->bool;
}
impl HasPart for[T]{
默认fn具有\u部分(&self,rhs:&self)->bool{
self.windows(rhs.len()).any(|curr | curr==rhs)
}
}
[u8]的impl HasPart{
fn有零件(&self,rhs:&self)->bool{
未实现!()//使用Knuth Morris Pratt
}
}
fn main(){
设vec1=vec![1,2,3,4,5];
设vec2=vec![2,3];//vec2是vec1的子字符串
设vec3=vec![1,5];//vec3不是vec3的子字符串
println!(“应该为true:{}”,vec1.has_part(&vec2));
println!(“应为false:{}”,vec1.has_part(&vec3));
}
Rust在标准库中不包含此项
通常,这是子字符串搜索问题,我们可以在任意字母表上定义它。根据我们可用的属性(仅可比较或可订购)确定我们可以使用的算法
使用子字符串搜索算法的好处是,该函数对所有输入都表现良好。蛮力搜索解决方案有一个最坏的情况,需要的时间是输入大小的二次方
i32
值的“字母表”是可排序的,因此可以调整双向算法(Rust标准库在str::find(&str)
内部使用)来实现这一点
Knuth-Morris-Pratt是一种适用于所有相等可比字母表的算法。它需要对我们正在搜索的模式进行预处理,并且需要与模式长度成比例的空间。它也很容易实现
我已经为Rust@的泛型元素编写了一个算法的实现,至少在撰写本文时,它还没有作为板条箱发布
哦,天哪。你可能是个书呆子狠狠地揍了我一顿。为此,我花了大量时间研究算法,这些算法只使用了
T:Eq
和常量空间(表示与内核兼容)。在撰写本文时,您可以使用以下板条箱:
fn is_sub<T: PartialEq>(mut haystack: &[T], needle: &[T]) -> bool {
if needle.len() == 0 { return true; }
while !haystack.is_empty() {
if haystack.starts_with(needle) { return true; }
haystack = &haystack[1..];
}
false
}
fn main() {
let vec1 = vec![1, 2, 3, 4, 5];
let vec2 = vec![2, 3]; // vec2 IS a substring of vec1
let vec3 = vec![1, 5]; // vec3 is NOT a substring of vec3
println!("should be true: {}", is_sub(&vec1, &vec2));
println!("should be false: {}", is_sub(&vec1, &vec3));
}
fn is_sub<T: PartialEq>(haystack: &[T], needle: &[T]) -> bool {
haystack.windows(needle.len()).any(|c| c == needle)
}
#![feature(specialization)]
pub trait HasPart {
fn has_part(&self, rhs: &Self) -> bool;
}
impl<T: PartialEq> HasPart for [T] {
default fn has_part(&self, rhs: &Self) -> bool {
self.windows(rhs.len()).any(|curr| curr == rhs)
}
}
impl HasPart for [u8] {
fn has_part(&self, rhs: &Self) -> bool {
unimplemented!() // use Knuth-Morris-Pratt
}
}
fn main() {
let vec1 = vec![1, 2, 3, 4, 5];
let vec2 = vec![2, 3]; // vec2 IS a substring of vec1
let vec3 = vec![1, 5]; // vec3 is NOT a substring of vec3
println!("should be true: {}", vec1.has_part(&vec2));
println!("should be false: {}", vec1.has_part(&vec3));
}