Так как у вас есть диапазон без увеличения (отсортированный по убыванию), вы можете использовать std :: lower_bound с оператором больше чем, как указано в комментариях. Тем не менее, это только даст вам первый результат мимо или равно вашему числу. Это не значит, что это «самый близкий», о чем вы просили.
Вместо этого я бы использовал std :: upper_bound, так что вам не нужно проверять равенство (на удвоении, чтобы сделать его еще хуже), а затем отбрасывать один, чтобы получить другую ограничивающую точку данных, и вычислять, какая из них на самом деле ближе. Наряду с некоторыми пограничными проверками:
#include <vector>
#include <algorithm>
#include <iostream>
#include <functional>
#include <iterator>
// for nonincreasing range of double, find closest to value, return its index
int index_closest(std::vector<double>::iterator begin, std::vector<double>::iterator end, double value) {
if (begin == end){
// we're boned
raise std::exception("index_closest has no valid index to return");
}
auto it = std::upper_bound(begin, end, value, std::greater<double>());
// first member is closest
if (begin == it)
return 0;
// last member is closest. end is one past that.
if (end == it)
return std::distance(begin, end) - 1;
// between two, need to see which is closer
double diff1 = abs(value - *it);
double diff2 = abs(value - *(it-1));
if (diff2 < diff1)
--it;
return std::distance(begin, it);
}
int main()
{
std::vector<double> data{ -12.5, -13.6, -14.8, -16.0, -17.1 };
for (double value = -12.0; value > -18.99; value = value - 1.0) {
int index = index_closest(data.begin(), data.end(), value);
std::cout << value << " is closest to " << data[index] << " at index " << index << std::endl;
}
}
вывод
-12 is closest to -12.5 at index 0
-13 is closest to -12.5 at index 0
-14 is closest to -13.6 at index 1
-15 is closest to -14.8 at index 2
-16 is closest to -16 at index 3
-17 is closest to -17.1 at index 4
-18 is closest to -17.1 at index 4
Обратите внимание, что, например, -14 ближе к -13,6, чем -14,8, как конкретный контрпример к вашей текущей рабочей точке. Также обратите внимание на важность входных данных в обеих конечных точках.
Оттуда вы можете взять кельвин [я]. Я не был доволен использованием внешнего массива данных для возвращаемого значения функции, когда вам не нужно это делать, поэтому я просто возвратил индекс.