You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

关于C++ lower_bound函数断言失败的问题咨询

关于C++ lower_bound函数断言失败的问题咨询

嗨,这个问题其实是对lower_bound的核心使用前提理解有偏差啦,咱们一步步捋清楚:

首先得敲黑板划重点:C++标准库的lower_bound函数有一个强制的使用前提——它要求传入的[first, last)区间必须是按升序排列的!这是它能正确工作的基础,因为底层是基于二分查找实现的,而二分查找的核心前提就是序列有序,对吧?

咱们来逐个拆解你的代码例子:

  • 第一个例子里,udata = {5,4},你传入的区间是udata.begin()+1udata.end(),也就是只有单个元素4的子区间。单个元素天然是升序有序的,所以lower_bound能正常定位到这个元素,返回的迭代器指向它,断言it != udata.end()自然通过。
  • 第二个例子里,udata = {5,4,1,2},你传入的区间是udata.begin()+1udata.end(),对应的子序列是{4,1,2}——这个序列完全不是升序的!直接违反了lower_bound的使用前提,此时函数的行为是未定义的(简单说就是结果随机,可能对也可能错),刚好这次返回了udata.end(),导致你的断言失败。

那该怎么解决这个问题呢?给你两个实用方向:

  • 如果你只是想在子区间里找到元素4,不追求二分查找的效率,直接用find函数就行——它不要求区间有序,就是线性遍历查找,完全适配这种场景。代码示例如下:
    vector<size_t> udata = {5,4,1,2};
    vector<size_t>::const_iterator it = find(udata.begin() + 1, udata.end(), 4);
    assert(it != udata.end()); // 这时候断言就会通过了
    
  • 如果坚持要用lower_bound来提升查找效率,那必须先把目标子区间升序排序,比如:
    vector<size_t> udata = {5,4,1,2};
    auto first = udata.begin() + 1;
    auto last = udata.end();
    sort(first, last); // 先把子区间排序成{1,2,4}
    vector<size_t>::const_iterator it = lower_bound(first, last, 4);
    assert(it != last); // 此时断言会通过,it指向4
    

记住哦,标准库的二分查找类函数(lower_boundupper_boundequal_range)全都是要求区间升序的,一旦违反这个前提,结果就完全不可控啦!

火山引擎 最新活动