私は実質的に同じ問題を抱えていたので、この汎用コードを書きました (std とは異なる名前空間を使用したいかもしれません ;) ) 以下のコードは、イテレータを、シーケンス内で val 以下の最大の要素に返します。 . [first ... last) での O(1) ランダム アクセスを想定して、N = std::difference(first, last) に対して O(N log N) 時間を使用します。
#include <iostream>
#include <vector>
#include <algorithm>
namespace std {
template<class RandomIt, class T>
RandomIt binary_locate(RandomIt first, RandomIt last, const T& val) {
if(val == *first) return first;
auto d = std::distance(first, last);
if(d==1) return first;
auto center = (first + (d/2));
if(val < *center) return binary_locate(first, center, val);
return binary_locate(center, last, val);
}
}
int main() {
std::vector<double> values = {0, 0.5, 1, 5, 7.5, 10, 12.5};
std::vector<double> tests = {0, 0.4, 0.5, 3, 7.5, 11.5, 12.5, 13};
for(double d : tests) {
auto it = std::binary_locate(values.begin(), values.end(), d);
std::cout << "found " << d << " right after index " << std::distance(values.begin(), it) << " which has value " << *it << std::endl;
}
return 0;
}
ソース: http://ideone.com/X9RsFx
コードは非常に汎用的で、std::vectors、std::arrays および arrays、またはランダム アクセスを許可する任意のシーケンスを受け入れます。仮定 (前提条件を読む) は、std::binary_search に必要なように、val >= *first であり、値 [first, last) がソートされていることです。
私が使用したバグや不正行為について自由に言及してください。