lower_bound返回第一个≥target的迭代器,即最左可插入位置;upper_bound返回第一个>target的迭代器,二者差值为target出现次数,均要求升序区间。

lower_bound 返回第一个 ≥ target 的位置
它找的是“能插在 target 前面而不破坏升序”的最左位置。只要元素值 >= target,就满足条件,且返回第一个匹配的迭代器。
常见错误是误以为它只返回 == target 的元素——其实当 target 不存在时,它会直接跳到第一个更大的元素(比如在 {1,3,5,7} 中查 4,返回指向 5 的迭代器)。
- 必须保证区间已升序排列,否则结果未定义
- 返回
last迭代器表示所有元素都 target - 配合
==判断存在性:if (it != vec.end() && *it == target)
upper_bound 返回第一个 > target 的位置
它找的是“所有 target 元素之后、下一个更大值的起始位置”。和 lower_bound 一样用二分,但判断条件更严格:只认 >,不认 ==。
典型陷阱是把它当成“最后一个 target 的位置”——它实际返回的是那个位置的 下一个 迭代器。所以在 {2,4,4,4,6} 中查 4,upper_bound 指向 6,不是最后一个 4。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 和
lower_bound共享同一套前提:升序 + 左闭右开区间 -
upper_bound - lower_bound就是target的出现次数(适用于重复元素) - 若想获取最后一个
== target的元素,得写if (low != up) { auto last_eq = up - 1; }
用自定义比较时,语义要反过来看
传 std::greater<int>()</int> 表示区间是降序的,此时:
-
lower_bound(..., val, greater<int>())</int>实际找第一个的位置(因为在降序中,“不小于”等价于“不大于”) -
upper_bound(..., val, greater<int>())</int>找第一个的位置 - 别硬记“升序时怎么、降序时怎么”,直接看比较谓词:函数内部用的是
comp(*it, val)还是comp(val, *it)?标准库约定是comp(value, element)形式用于upper_bound,但更稳妥的做法是——写个测试小数组跑一遍
vector 里查完记得转下标,别直接解引用 end()
新手常犯的崩溃操作:auto it = lower_bound(v.begin(), v.end(), x); cout ——当 <code>x 大于所有元素时,it == v.end(),解引用必崩。
- 安全做法:先判
it != v.end()再访问*it - 转下标统一用
it - v.begin(),不要手算或加减 1 - 注意:返回的是迭代器,不是 bool 或 int,别和
std::binary_search混用
实际边界计算永远依赖 pair:一个 lower_bound,一个 upper_bound,中间那段才是你要的稳定区间。漏掉任一端,统计、删除或范围遍历都会出错。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










