В библиотеке std
есть алгоритм, который почти точно выполняет то, что вы просите: std::lower_bound
Возвращает итератор, указывающий на первый элемент вдиапазон [первый, последний), который не меньше (то есть больше или равен) значению, или последний, если такой элемент не найден.
Вы можете использовать это, чтобы найти первый элемент, который являетсяравно или выше, чем ваша цель. Ответ - либо число, предшествующее ему.
Проверьте следующий пример:
int find_closest(const vector<int>& A, const int a)
{
if(A.size() <=0)
throw std::invalid_argument("empty array");
const auto lb = std::lower_bound(A.begin(), A.end(), a);
int ans = lb!= A.end() ? *lb : A.back();
if (lb != A.begin()) {
auto prec = lb - 1;
if (abs(ans - a) > abs(*prec - a))
ans = *prec;
}
return ans;
}
Сложность этого подхода логарифмическая по размеру входной коллекцииlower_bound
выполняет бинарный поиск. Это намного быстрее, чем простое решение, в котором вы будете перебирать всю коллекцию и проверять каждый элемент один за другим.