量产小妙招---c++之std::lower_bound

1 背景

        在数组(递增或者递减)中,想要查找目标值附近的一个元素,那么该怎么操作呢?比如需要在含有时间序列的数据结构中查找1s后自车或者他车的位置。

        伴随着上面的问题,引入了本篇博客要讨论的一个话题:std::lower_bound()。因为该方法在量产中会经常使用,因此介绍给各位读者朋友们,希望有所帮助。

2b5d57b2587f42a4bf50ee154b5577aa.png

2 lower_bound介绍

        std::lower_bound()是 C++ 标准库中的一个函数模板,定义在 <algorithm> 头文件中。它用于在已排序的范围内查找第一个不小于给定值的元素的位置。这个函数是二分查找算法的实现,可以高效地在一个有序数组或容器中查找元素。以下是 std::lower_bound()的一些关键特性:

  • 时间复杂度:对于具有 n 个元素的容器, std::lower_bound 的时间复杂度为 O(log n),这使得它非常适用于大规模数据查找。
  • 使用场景:当容器(如  std::vector、 std::array 或  std::deque)已经排序,并且你需要查找一个元素或者其插入点时使用。
  • 返回值:返回一个迭代器,指向不小于给定值的第一个元素。如果所有元素都小于给定值,则返回容器的末尾迭代器。

        它的函数原型如下:

template <class ForwardIterator, class T>
ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last, const T& value);

        其中,'first' 和 'last' 是容器的迭代器范围,'value' 是要查找的目标值。

        std::lower_bound()函数返回一个迭代器,指向容器中第一个不小于目标值的元素。如果目标值不存在于容器中,则返回一个迭代器,指向第一个大于目标值的元素。

2.1 简单示例

        下面是一个使用std::lower_bound()函数的示例代码:

#include <iostream>
#include <algorithm>
#include <vector>

int main() {
    // 定义有序数组
    std::vector<int> numbers = {1, 3, 5, 7, 9, 11, 13};
    // 目标值
    int target = 7;
    // 使用 std::lower_bound() 查找目标值
    auto it = std::lower_bound(numbers.begin(), numbers.end(), target);

    if (it!= numbers.end() && *it == target) {
        std::cout << "目标值 " << target << " 在容器中找到,位置为:" << std::distance(numbers.begin(), it) << std::endl;
    } else {
        std::cout << "目标值 " << target << " 不在容器中" << std::endl;
    }

    return 0;
}

        在上述示例中,创建了一个有序的整数向量 'numbers',并定义了一个目标值 'target'。然后,使用 'std::lower_bound()' 函数在向量中查找目标值。如果找到目标值,输出其位置;否则,输出目标值不在容器中。

2.2 自定义比较函数

        上面说过lower_bound(),其实upper_bound()也差不多,这两个函数都支持自定义比较,如果想实现自定义比较函数则只需要记住以下原则即可:

        自定义比较函数都是实现"<"运算符操作;lower_bound找左边界(下限),遍历元素在左(下);upper_bound找右边界(上限),被遍历元素在右(上)。

        根据以上原则我们可以猜测到lower_bound和upper_bound的各自终止条件:

  • lower_bound()在比较函数(记为cmp)返回false时终止查找(找到前cmp返回true)。
  • upper_bound()在比较函数(记为cmp)返回true时终止查找(找到前cmp返回false)。
#include <iostream>
#include <vector>
#include <algorithm>

struct Elem {
    int val = 0;
    Elem(int val): val(val) {}
}
// 自定义比较函数,目标是实现<操作,
// lower_bound找下边界(左),elem在下(左)
bool LowerCompare(Elem elem, int target) {
    return elem.val < target; //实现<
}

// upper_bound找上边界(右),elem在上(右)
bool UpperCompare(int target, Elem elem) {
    return target < elem.val; //实现<
}

int main() {
    std::vector<Elem> vec = {1, 2, 4, 4, 4, 6, 7};
    int target = 4;

    // 使用自定义比较函数进行 lower_bound 查找
    auto lower = std::lower_bound(vec.begin(), vec.end(), target, LowerCompare);
    if (lower != vec.end()) {
        int lowerIndex = lower - vec.begin();
        std::cout << "Lower bound of " << target << " is at index: " << lowerIndex << " with value: " << *lower << std::endl;
    } else {
        std::cout << "Lower bound of " << target << " not found!" << std::endl;
    }

    // 使用自定义比较函数进行 upper_bound 查找
    auto upper = std::upper_bound(vec.begin(), vec.end(), target, UpperCompare);
    if (upper != vec.end()) {
        int upperIndex = upper - vec.begin();
        std::cout << "Upper bound of " << target << " is at index: " << upperIndex << " with value: " << *upper << std::endl;
    } else {
        std::cout << "Upper bound of " << target << " not found!" << std::endl;
    }

    return 0;
}

 

  • 18
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

智能汽车人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值