我需要一个带矢量(假设为已排序)和一个值的函数,并返回大于小于或等于该值的最接近的数字 数字,最好使用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,但是找不到比这更好的解决方案了。
答案 0 :(得分:16)
提醒:
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
答案 1 :(得分:5)
您只能将std::lower_bound
和std::upper_bound
与二进制谓词一起使用,该二进制谓词与容器的顺序相匹配。因此,您无法按<
排序,然后使用其他二元谓词(例如<=
或>
)。所以你的“kludge”实际上是正确的事情。反向排序的向量是您要用于查找小于或等于该值的元素的排序条件。 (否则,如果您实际搜索的值大于或等于,则可以使用std::lower_bound
。)
答案 2 :(得分:3)
需要C ++ 11:
hi
答案 3 :(得分:2)
这样的东西可行......取最小的最接近的值:
可以作为模板或其他东西,而不是那些了解模板编程的人。 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;
}
答案 4 :(得分: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);
}