std::binary_search只返回bool值,不返回下标;需获取下标应使用lower_bound或upper_bound,它们返回迭代器,可转为索引。

binary_search 是什么,它能直接返回下标吗
std::binary_search 只返回 true 或 false,表示元素是否存在。它**不返回位置**,也不保证是第一个或最后一个匹配项。如果你需要下标(比如想修改、插入或继续处理),不能只靠 binary_search。
想查下标?用 lower_bound 或 upper_bound
真正做“二分查找并取位置”的主力是 lower_bound 和 upper_bound:
-
lower_bound(first, last, val)返回第一个 ≥val的迭代器 -
upper_bound(first, last, val)返回第一个 >val的迭代器 - 两者都要求容器已升序排列(默认比较),否则行为未定义
- 若没找到,返回
last—— 一定要检查是否越界再解引用
例如查值为 5 的起始位置:
std::vectorv = {1, 3, 5, 5, 5, 7, 9}; auto it = std::lower_bound(v.begin(), v.end(), 5); if (it != v.end() && *it == 5) { int idx = it - v.begin(); // idx == 2 }
自己写二分循环?注意边界和死循环
手写时最容易错的是 left/right 更新方式和终止条件。常见错误包括:
立即学习“C++免费学习笔记(深入)”;
- 用
却漏掉mid的更新,导致死循环 - 用
但right初始化为size(),却忘了mid计算可能越界(实际不会,但逻辑易混) - 查第一个/最后一个匹配项时,
right = mid还是right = mid - 1搞反
安全写法(查第一个匹配):
int left = 0, right = v.size();
while (left < right) {
int mid = left + (right - left) / 2;
if (v[mid] < target) {
left = mid + 1;
} else {
right = mid;
}
}
// 循环结束时 left == right,检查 v[left] == target性能和兼容性:vector vs list,排序前提不能忘
binary_search、lower_bound 等函数对随机访问迭代器(如 vector、array)是 O(log n),对 list 或 forward_list 虽然能编译通过,但实际是 O(n),因为无法 O(1) 跳转到中间——别被接口迷惑。
另一个关键点:它们**不负责排序**。传入未排序的 vector,结果完全不可预测。如果数据动态变化,每次查前都 sort?那总代价是 O(n log n),远不如一次建好有序结构(比如 std::set 或维护插入有序)。
真正在意下标、又频繁增删,vector + 手写二分未必最优;考虑 std::set 或 std::map,它们底层红黑树天然支持等价查找,但不提供下标——这事没有银弹,得看你的读写比和是否需要索引。









