C++ 从上面查找向量中最近值的优雅方法

C++ 从上面查找向量中最近值的优雅方法,c++,algorithm,stl,C++,Algorithm,Stl,我需要一个函数,它接受一个向量(假定已排序)和一个值,并返回[edit]大于或等于该数字的最近数字,最好使用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

我需要一个函数,它接受一个向量(假定已排序)和一个值,并返回[edit]大于或等于该数字的最近数字,最好使用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"
struct ClosestCmp{
布尔运算符()(常量int&x,常量int&y){return x>y;}
};
//假设vec已排序
最接近的整数(常量标准::向量和向量,整数值)
{
std::vector::const\u reverse\u迭代器cri=
std::下限(vec.rbegin(),vec.rend(),value,ClosestCmp());
如果(cri!=vec.rend()){
返回*cri;
}
返回-1;
}
// ...
向量推回(1);
向量推回(2);
向量推回(4);
向量推回(5);
标准::cout提醒:

  • 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;
}

您只能将
std::lower_bound
std::upper_bound
与匹配容器顺序的二进制谓词一起使用。因此,您不能按
对小于或等于的最大值进行排序。您可以使用此函数

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);
}
int最近(std::vector const&vec,int值){
auto const it=std::下限(vec.begin(),vec.end(),value);
如果(it==vec.begin()){return-1;}
否则返回*(it-1);
}
需要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);
    });
}
模板
最近的InputIterator(InputIterator first、InputIterator last、ValueType值)
{
返回std::min_元素(第一、最后、[&](值类型x、值类型y)
{   
返回std::abs(x-值)
2不大于或等于3,我想您希望打印4?更正:我需要小于或等于该值的最接近数字,而不是更大的数字。我的错。+1我同意这个答案,但是OP的问题是矛盾的。你是对的。我的意思是说小于,而不是大于,价值。非常感谢。因此,输出需要是:2 Hello,链接现在是broken@kyriakosSt:链接已删除:)是的,我想你是对的。STL主要用于使用
STL算法处理基于二进制谓词的排序范围。默认谓词是
,我认为提供一个示例总是好的。我考虑过这个解决方案。但是,如果vec的第一个元素等于value,则它将失败。这并没有得益于向量已排序的事实。复杂性总是线性的,这是真的。但它很优雅:)如果排序,可以使用下界同级,但对于未排序的容器,这是一个很好的解决方案。如果在值的最小差异的意义上使用最接近的,则此解决方案效果更好。对于向量
{1,4}
最近(2)
返回
1
最近(3)
返回
4
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);
}
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);
    });
}