One of the most common problems programmers have to solve is retrieving specific data — finding the needle in the haystack.
To make this simpler, languages provide standard tools to perform this task:
in particular, this post focuses on C++'s `lower_bound` and `upper_bound`.
Personally, I find that the documentation for these functions is quite unclear and verbose.
For example, [cppreference.com](https://en.cppreference.com/w/cpp/algorithm/lower_bound)
describes `lower_bound` like this:
```
Searches for the first element in the partitioned range [first, last) which is
**not** ordered before value.
```
That sounds like gibberish, and is too technical to quickly understand.
For that reason, I'm making this blog post to explain my own mental model of these functions.
## refresher on binary search
First, it's important to understand how `lower_bound` and `upper_bound` work under the hood.
As you know, finding words in a dictionary is relatively fast.
This is possible because the words are in alphabetical order.
If the words weren't ordered, you'd have to look through every single word in the dictionary, one by one.
That would be an excruciating, and much slower process.
Because of the ordering, you can rapidly narrow down the word you want.
Computers can do the same with ordered data: this is called *binary search*,
and is what powers `lower_bound` and `upper_bound`.
For example, say our dictionary is 1000 pages, and the computer wants to look for the word "rabbit".
These are the steps it takes:
1. Start at exactly page 500.
2. See the word "murmur", so go forwards to page 750.
3. See the word "sunny", so go backwards to page 625.
4. And so on.
This is called "binary search" because we halve the region we are looking in every time (we pick either the left half, or the right half.)
For step 1, the computer is halving the range `1-1000`.
In step 2, `500-1000`. Then for step 3, `500-750`.
This is like the way humans look at dictionaries, but more structured.
Anyways, this is not intended to be a full explanation of binary search: refer to [Tom Scott's video](https://youtube.com/watch?v=KXJSjte_OAI) about it for more information.
## lower bound and upper bound
Back to the real subject of this post: `lower_bound` and `upper_bound` in C++.
What I used to understand of these functions is that they use binary search to find elements in a sorted container.
However, I didn't get what differentiated them.
Again, if you read solely the documentation about these functions, it's not easily comprehensible.
First of all, say we wish to search for the integer `k` (k for key) in a sorted vector (array) of integers `v`.
We can find the lower and upper bounds with these function calls:
```
// (you could use auto here instead of the verbose type)