Finding the closest or exact key in a std::map

For this, you can use either std::map::lower_bound

Returns an iterator pointing to the first element that is not less than key.

or std::map::equal_range

Returns a range containing all elements with the given key in the container.


In your case, if you want the closest entry, you need to check both the returned entry and the one before and compare the differences. Something like this might work

std::map<double, double>::iterator low, prev;
double pos = 3.0;
low = map.lower_bound(pos);
if (low == map.end()) {
    // nothing found, maybe use rbegin()
} else if (low == map.begin()) {
    std::cout << "low=" << low->first << '\n';
} else {
    prev = std::prev(low);
    if ((pos - prev->first) < (low->first - pos))
        std::cout << "prev=" << prev->first << '\n';
    else
        std::cout << "low=" << low->first << '\n';
}

"best performance possible" - given you insert elements in increasing order, you can push_back/emplace_back them into a std::vector then use std::lower_bound - you'll get better cache utilisation because the data will be packed into contiguous address space.


You could of course use lower_bound and upper_bound, which are logarithmic in runtime. And they should do what you want.

std::map<double,double>::iterator close_low;
//... your_map ...
close_low=your_map.lower_bound (current_length);

This should give you an iterator to the the first map element whose key is < current length. Do likewise with upper_bound and you have your time surrounded.

Tags:

C++