如何检查vector_a
的所有元素是否以与vector_b
相同的顺序出现?
vector_b
可能非常长,没有假设它已排序,但它没有重复元素。
我没有找到Vec
或itertools中实现该方法,因此我尝试通过以下方式实现:
- 从
vector_b
创建哈希映射将value->index
映射 - 遍历
vector_b
并检查:- 元素存在于哈希映射中
- 索引严格大于前一个元素的索引
由于创建哈希映射不太空间有效,因此我对此并不满意。
按顺序在干草堆中搜索needle的每个元素。每当找到匹配元素时,仅在剩余部分的干草堆中继续搜索。每次匹配元素时,可以通过取新的子切片来很好地表达这一点。
fn is_subsequence<T: PartialEq>(needle: &[T], mut haystack: &[T]) -> bool {
for search in needle {
if let Some(index) = haystack.iter().position(|el| search == el) {
haystack = &haystack[index + 1..];
} else {
return false;
}
}
true
}
assert!(is_subsequence(b"", b"0123456789"));
assert!(is_subsequence(b"0", b"0123456789"));
assert!(is_subsequence(b"059", b"0123456789"));
assert!(is_subsequence(b"345", b"0123456789"));
assert!(is_subsequence(b"0123456789", b"0123456789"));
assert!(!is_subsequence(b"335", b"0123456789"));
assert!(!is_subsequence(b"543", b"0123456789"));
切片只是一个指针和大小,存储在栈上,所以这不会进行新的分配。它运行的时间复杂度为 O(n)
并且应该接近于最快的实现 - 或者至少在同一范围内。
haystack
变为可变引用可能会有什么后果?我认为,如果这必须成为库的一部分,则允许不可变引用更为优选,对吗? - roynalnarutohaystack
不是可变引用。只有局部变量是可变的(它被重新分配为更小的子切片),但原始切片不能被改变:这需要参数为 haystack: &mut [T]
。 - Peter Hallfn contains<T: PartialEq>(needle: &[T], haystack: &[T]) -> bool {
let mut idx = 0;
for it in needle {
while (idx < haystack.len()) && (&haystack[idx] != it) {
idx += 1;
}
if idx == haystack.len() {
return false;
}
}
return true;
}
vector_b
中简单地进行线性搜索,以查找vector_a
的第一个元素。一旦找到它,就搜索下一个元素,以此类推。由于vector_b
没有重复项,因此您永远不需要再次备份,所以这是vector_b
长度的线性时间,并且只需要恒定的额外空间。 - Sven Marnachvector_a
中剩余的元素比vector_b
中的元素多,就退出循环,因为这时已经不可能找到所有的元素了。 - Sven MarnachCopy
、Eq
和PartialEq
派生的结构体。 - roynalnarutoa = [1, 2]
和b = [1, 0, 2]
,算法应该返回true
还是false
(b
是否包含与a
相同顺序的相同元素)?或者a
的元素是否应该在b
中连续存在? - Jmbtrue
。连续性并非必需的。 - roynalnaruto