ベクトル(ソートされていると想定)と値を受け取り、最も近い数値を返す関数が必要です[編集] より大きい その数以下、できればSTLのアルゴリズムを使用。 std :: lower_bound()を使用した解決策を考え出しましたが、それは扱いにくく醜いようです:
struct ClosestCmp {
bool operator()(const int & x, const int & y) { return x > y; }
};
// vec is assumed to be sorted
int closest(const std::vector<int> & vec, int value)
{
std::vector<int>::const_reverse_iterator cri =
std::lower_bound(vec.rbegin(), vec.rend(), value, ClosestCmp());
if (cri != vec.rend()) {
return *cri;
}
return -1;
}
// ...
vec.Push_back(1);
vec.Push_back(2);
vec.Push_back(4);
vec.Push_back(5);
std::cout << closest(vec, 2) << "\n"; // Should ouput "2"
std::cout << closest(vec, 3) << "\n"; // Should ouput "2"
std::cout << closest(vec, 4) << "\n"; // Should ouput "4"
誰かがよりエレガントな方法を提案できますか?比較関数や逆反復子を必要とせずにSTLアルゴリズムを使用しているのでしょうか?私はSTLを調べましたが、これよりも良い解決策を見つけることができませんでした。
std::lower_bound
およびstd::upper_bound
は、コンテナーの順序と一致するバイナリ述語でのみ使用できます。したがって、<
で並べ替えてから、別のバイナリ述語(<=
または>
など)を使用することはできません。したがって、「kludge」は実際には正しいことです。逆にソートされたベクトルは、値以下の要素を見つけるために使用する順序付け基準です。 (それ以外の場合は、実際に以上の値を検索する場合は、std::lower_bound
を使用できます。)
注意:
std::lower_bound
:比較しない最初の値を返しますstd::upper_bound
:厳密に比較する最初の値を返しますあなたの説明から、std::lower_bound
はすでに完全に適合しているように見えますが、何が問題になっていますか。
int closest(std::vector<int> const& vec, int value) {
auto const it = std::lower_bound(vec.begin(), vec.end(), value);
if (it == vec.end()) { return -1; }
return *it;
}
これは次のように使用されます。
int main() {
std::vector<int> vec;
vec.Push_back(2);
vec.Push_back(4);
std::cout << closest(vec, 2) << "\n";
std::cout << closest(vec, 3) << "\n";
std::cout << closest(vec, 4) << "\n";
}
出力:
2
4
4
C++ 11が必要:
template<typename InputIterator, typename ValueType>
InputIterator closest(InputIterator first, InputIterator last, ValueType value)
{
return std::min_element(first, last, [&](ValueType x, ValueType y)
{
return std::abs(x - value) < std::abs(y - value);
});
}
このような何かがうまくいくでしょう...最も小さい値をとります:
テンプレートプログラミングを理解している人のために、テンプレートまたは何かの代わりに多作にすることができます。 http://ideone.com/ff46ax
#include <iostream>
#include <vector>
#include <map>
#include <stdlib.h>
int main()
{
int comparevalue = 3;
typedef std::vector<int> intvec;
intvec myvec;
myvec.Push_back(1);
myvec.Push_back(2);
myvec.Push_back(4);
myvec.Push_back(5);
myvec.Push_back(6);
myvec.Push_back(7);
typedef std::map<int, int> intmap;
intmap mymap;
for (intvec::const_iterator itr = myvec.begin(); itr != myvec.end(); ++itr)
mymap.insert(std::make_pair(abs(*itr-comparevalue), *itr));
std::cout << "difference:" << mymap.begin()->first << "\n";
std::cout << "value:" << mymap.begin()->second;
return 0;
}
以下の最大のものについては、この関数を使用できます
int closest(std::vector<int> const& vec, int value) {
auto const it = std::lower_bound(vec.begin(), vec.end(), value);
if (it == vec.begin()) { return -1; }
else return *(it - 1);
}