lower_bound和upper_bound底层详解

lower_bound

这里先讲一下这个函数的作用,找出第一个 >= target(val)的值
第一和二个参数是迭代器,用来标记起始和结束的,第三个参数是用来比较的target值,第四个参数则是比较规则,我们继续来看我标记的下面几个重点。
在这里插入图片描述
_Pred(*_UMid, _Val)用比较的规则去比较mid(UMid)和Val的关系返回值是true/false;
_Next_iter(_UMid) 把mid 指针++;
由此可以很清晰推出,上面的值是true则left = mid + 1, false则right = mid这样的关系
又由于此函数是找出第一个 >=target的值,而什么时候会把left = mid +1呢,只有target > mid时候,
target <= mid,则right = mid;
所以我们要传第四个参数时候,其应该这样写,
这边举一个lamda表达式作为第四个参数的例子,[](int &mid,int& target){
return target > mid;
}

upper_bound

这里先讲一下这个函数的作用,找出第一个 > target(val)的值
第一和二个参数是迭代器,用来标记起始和结束的,第三个参数是用来比较的target值,第四个参数则是比较规则,我们继续来看我标记的下面几个重点。
在这里插入图片描述

_Pred(_Val, *_UMid)用比较的规则去比较Val和mid(UMid)的关系注意!!!!这里的val和mid参数和上面的是反的,返回值是true/false;
_Next_iter(_UMid) 把mid 指针++;
由此可以很清晰推出,上面的值是 true则right = mid,false则left = mid + 1这样的关系
又由于此函数是找出第一个 > target的值,而什么时候 会把right = mid,只有当target < mid,而只有target >= mid时候,left = mid +1,
所以我们要传第四个参数时候,其应该这样写,
这边举一个lamda表达式作为第四个参数的例子,[](int& target,int &mid){
return target < mid;//只需要把上述两个参数位置互换,和大于小于号翻转即可
}

<think>好的,我现在需要帮用户解答关于C++lower_boundupper_bound自定义比较函数中大于小于符号的意义的问题。首先,我需要回忆这两个函数的基本用法它们在STL中的作用。 根据用户提供的引用内容,知道lower_boundupper_bound底层是二分查找实现的,且它们的自定义比较函数的参数顺序返回逻辑是相反的。这可能比较函数的设计有关。接下来,我需要明确这两个函数在默认情况下自定义比较时的行为差异。 首先,lower_bound默认用于在有序区间中找到第一个不小于目标值的位置,而upper_bound找到第一个大于目标值的位置。当使用自定义比较函数时,函数的参数顺序会影响比较的方向。例如,默认的比较是less,即comp(a, b)为a < b。而如果用户自定义的比较函数是greater,即a > b,那么整个查找逻辑会反转,lower_bound可能会变成寻找第一个不大于目标值的位置。 需要解释清楚比较函数的参数顺序符号的关系。例如,在lower_bound中,第三个参数是val,而比较函数的形式是comp(element, val),当使用默认的less时,相当于检查element < val。而当使用自定义的greater比较函数时,比较的是element > val,这会影响查找的方向。 另外,用户提到的引用中说明lower_boundupper_bound的自定义比较函数的参数是相反的,返回逻辑也相反。这意味着在lower_bound中,比较函数可能是comp(element, val),而在upper_bound中可能是comp(val, element),或者参数顺序不同,导致逻辑相反。需要进一步验证这一点。 可能需要用示例代码来说明不同比较函数对结果的影响。例如,当数组是降序排列时,使用greater比较函数,此时lower_bound的作用是找到第一个不大于val的元素的位置。同时,需要指出比较函数中的符号决定了查找的条件,比如使用<还是>会影响元素被认为是“合格”的条件。 最后,总结比较函数中的符号如何改变查找的语义,以及在升序降序数组中的应用情况。确保用户能够理解为什么自定义比较函数需要特别注意参数顺序符号方向,以及如何正确使用它们来实现不同的查找需求。</think>### C++ lower_bound/upper_bound 自定义比较函数详解 #### 一、函数默认行为 在升序序列中(默认使用`std::less`): - `lower_bound`:返回第一个**不小于**目标值的元素位置,对应条件 $x \geq val$ - `upper_bound`:返回第一个**大于**目标值的元素位置,对应条件 $x > val$ ```cpp // 默认比较函数为 less auto pos1 = lower_bound(v.begin(), v.end(), 5); // 找第一个 >=5 的位置 auto pos2 = upper_bound(v.begin(), v.end(), 5); // 找第一个 >5 的位置 ``` #### 二、自定义比较函数的参数逻辑 自定义比较函数`comp`需满足**严格弱序**关系: ```cpp bool comp(const T& a, const T& b) ``` - `lower_bound`调用方式:`comp(*iter, value)` - `upper_bound`调用方式:`comp(value, *iter)` 注意参数顺序的镜像对称性[^1]: ```cpp // 降序序列示例(使用 greater) auto pos3 = lower_bound(v.begin(), v.end(), 5, greater<int>()); // 找第一个 <=5 的位置 auto pos4 = upper_bound(v.begin(), v.end(), 5, greater<int>()); // 找第一个 <5 的位置 ``` #### 三、符号意义对照表 | 比较方向 | lower_bound条件 | upper_bound条件 | |---------|-----------------|-----------------| | < (默认) | $x \geq val$ | $x > val$ | | > (降序) | $x \leq val$ | $x < val$ | #### 四、数学表达式验证 对于有序序列 $[a_1, a_2,...,a_n]$,当使用比较函数 $f(x,y)$ 时: - `lower_bound` 满足 $\exists k, f(a_k, val) = false \land \forall i<k, f(a_i, val) = true$ - `upper_bound` 满足 $\exists k, f(val, a_k) = true \land \forall i<k, f(val, a_i) = false$ #### 五、应用示例 ```cpp vector<int> v{10,8,6,4,2}; // 查找第一个 <=5 的元素 auto it = lower_bound(v.begin(), v.end(), 5, [](int x, int val){ return x > val; }); // 比较函数 x > val 返回false时停止 // 结果指向6(因6>5继续右移,最终指向4) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值