Reputation: 339
How can I check if all elements of vector_a
also appear in the same order as vector_b
?
vector_b
could be very long, there is no assumption that it is sorted, but it does not have duplicate elements.
I could not find a method implemented for Vec
or in itertools, so I tried implementing by doing:
vector_b
mapping value -> index
vector_b
and check that:
I am not really happy with this as it is not space efficient due to the creation of the hashmap.
Upvotes: 4
Views: 758
Reputation: 58875
Search for each element of the needle in the haystack in order. Each time you find a matching element, only continue the search in the remaining portion of the haystack. You can express this nicely by taking a new subslice of of the haystack each time you match an element.
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"));
A slice is just a pointer and a size, stored on the stack, so this does no new allocations. It runs in O(n)
time and should be close to the fastest possible implementation - or at least in the same ballpark.
Upvotes: 6
Reputation: 23463
Easiest way to do it is to iterate the two vectors jointly:
fn 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;
}
Upvotes: 4