Created
July 30, 2023 04:18
-
-
Save ttsugriy/48ce5fbbf485f4ea06400c4049eb2eb0 to your computer and use it in GitHub Desktop.
binary_search_slice using partition_point
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pub fn binary_search_slice_new<'d, E, K>(data: &'d [E], key_fn: impl Fn(&E) -> K, key: &K) -> &'d [E] | |
where | |
K: Ord, | |
{ | |
let size = data.len(); | |
let start = data.partition_point(|x| key_fn(x) < *key); | |
// At this point `start` either points at the first entry with equal or | |
// greater key or is equal to `size` in case all elements have smaller keys | |
// Invariant: start == size || key_fn(&data[start]) >= *key | |
if start == size || key_fn(&data[start]) != *key { | |
return &[]; | |
}; | |
// Invariant: start < size && key_fn(&data[start]) == *key | |
// Find the first entry with key > `key`. Skip `start` entries since | |
// key_fn(&data[start]) == *key | |
// Invariant: offset == size || key_fn(&data[offset]) >= *key | |
let offset = start + 1; | |
let end = data[offset..].partition_point(|x| key_fn(x) <= *key) + offset; | |
// Invariant: end == size || key_fn(&data[end]) > *key | |
&data[start..end] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment