У меня есть простой std::vector
содержащий некоторые числа, которые сортируются (в порядке возрастания). Я хочу найти элемент, до сих пор использую:
return std::lower_bound(vec.begin(), vec.end(), needle);
Где needle
- элемент, который я ищу. Однако мой вектор имеет тенденцию быть довольно длинным (миллионы элементов), но большую часть времени контент относительно предсказуем в некотором смысле, что если первый элемент равен нулю, а последний элемент N
, то элементы между ними имеют значение, близкое к (N * index) / vec.size()
и, следовательно, предсказуемо.
Есть ли модификация нижней границы, которая будет принимать подсказку (подобно тому, как это делается std::map::emplace_hint()
), например:
assert(!vec.empty());
std::vector<int>::iterator hint = vec.begin() + std::min(vec.size() - 1,
(needle * vec.size()) / vec.back());
if(*hint > needle)
return std::lower_bound(vec.begin(), hint, needle);
else
return std::lower_bound(hint, vec.end(), needle);
Это будет работать, но lower_bound
игнорирует, что он близок к решению и, скорее всего, начнет разделять интервал на половинки (смотря, где мы знаем, что игла, скорее всего, нет), делая излишне много шагов. Я знаю, что существует алгоритм, который начинается с шага 1, который он удваивает, пока он не перекроет иглу, а затем выполняет бинарный поиск в заданном интервале.
Я забыл, что такое имя алгоритма. Это реализовано в STL?