C++中lower_bound 与 upper_bound 函数详解

目录

一.核心定义与核心区别

lower_bound(下界函数)

upper_bound(上界函数)

二.使用前提与参数说明

1. 必须满足的前提

2. 函数参数

3.返回值

 三.用法

(1)判断目标值是否存在

(2)计算目标值的出现次数(统计重复元素)

(3)在有序容器中插入元素(保持有序)

(4)自定义比较函数(降序)


lower_bound 和 upper_bound 是 C++ 标准库 <algorithm> 头文件中的二分查找算法,专门用于在有序区间中高效定位元素

一.核心定义与核心区别

函数的头文件: #include <algorithm>

lower_bound(下界函数)

功能:在 [first, last) 区间内,找到第一个大于或等于(≥)目标值 target 的元素,返回其迭代器。

upper_bound(上界函数)

功能:在 [first, last) 区间内,找到第一个大于(>)目标值 target 的元素,返回其迭代器。

函数

判断条件

定位结果

lower_bound

≥ target

目标值的“左边界”(包含自身)

upper_bound

> target

目标值的“右边界”(不包含自身)


二.使用前提与参数说明

1. 必须满足的前提

  • 查找区间 [first, last) 必须是升序排列的(默认使用 < 运算符比较)。
  • 若区间无序,函数行为未定义(结果不可预测)

2. 函数参数

1. 默认比较(升序,使用 < 运算符)

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

2. 自定义比较(升序,可传入自定义规则,如 greater<int>() 实现降序查找)

template <class ForwardIterator, class T, class Compare> ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last, const T& val, Compare comp);

upper_bound 参数格式完全相同,仅判断逻辑不同

  • ForwardIterator就是一个迭代器,如vector< int > v,v数组的首元素就是 v.begin()
  • T&val , 就是一个T类型的变量
  • Compare 就是一个比较器,可以传仿函数对象,也可以传函数指针
  • first/last:迭代器,指定查找的左闭右开区间 [first, last)
  • val:要查找的目标值
  • comp:可选参数,自定义比较函数/谓词(如 greater<int>() 用于降序区间)

3.返回值

  • 成功找到符合条件的元素:返回指向该元素的迭代器
  • 未找到(所有元素都不满足条件):返回 last 迭代器(区间末尾的“哨兵”,不指向任何有效元素)

 三.用法

(1)判断目标值是否存在

若 lower_bound 返回的迭代器不等于 last,且该迭代器指向的元素 等于 target,则 target 存在

vector<int> v = {1,3,5,7,9}; int target = 5; auto it = lower_bound(v.begin(), v.end(), target); if (it != v.end() && *it == target) { cout << "目标值 " << target << " 存在" << endl; // 输出:目标值 5 存在 }

(2)计算目标值的出现次数(统计重复元素)

upper_bound 与 lower_bound 的迭代器差值,即为 target 在有序区间中的出现次数(因为两者之间的元素都等于 target)

vector<int> v = {1,3,5,5,5,7,9}; int target = 5; auto left = lower_bound(v.begin(), v.end(), target); // 指向第一个 5(索引 2) auto right = upper_bound(v.begin(), v.end(), target); // 指向 7(索引 5) int count = right - left; // 5 - 2 = 3,即 5 出现 3 次 cout << "目标值 " << target << " 出现次数:" << count << endl; 

(3)在有序容器中插入元素(保持有序)

利用 lower_bound 找到插入位置,直接插入,无需手动排序

vector<int> v = {1,3,7,9}; int insert_val = 5; // 找到第一个 ≥5 的位置(即 7 之前),插入 5 auto pos = lower_bound(v.begin(), v.end(), insert_val); v.insert(pos, insert_val); // 插入后 v = {1,3,5,7,9},仍保持升序

(4)自定义比较函数(降序)

当区间为降序时,需传入 greater<> 作为比较函数

vector<int> v_desc = {10, 8, 6, 4, 2, 1}; int target = 4; // 找第一个 ≤4 的元素(降序中 lower_bound 逻辑变为“≤”) auto it_lower = lower_bound(v_desc.begin(), v_desc.end(), target, greater<int>()); // 找第一个 <4 的元素(降序中 upper_bound 逻辑变为“<”) auto it_upper = upper_bound(v_desc.begin(), v_desc.end(), target, greater<int>()); cout << "降序中 ≥4 的第一个元素:" << *it_lower << endl; // 输出:4 cout << "降序中 >4 的第一个元素:" << *it_upper << endl; // 输出:2 

Read more

Python从0到100完整学习指南(必看导航)

Python 从 0 到 100 完整学习路线(2025–2026 实用版) 这是一条目前在中文社区被验证最多次、性价比最高、就业/副业/考研/转行都适用的 Python 学习路径。 分为 8 个大阶段,每个阶段给出: * 核心目标 * 推荐学习时长(每天 2–4 小时估算) * 最值得学的资源(2025–2026 仍活跃且评价最高的) * 必须掌握的技能清单 * 阶段性小目标 / 实战项目建议 阶段划分总览表 阶段名称目标人群建议时长累计总时长核心关键词0准备期完全零基础3–7 天1 周环境、IDE、学习心态1Python 基础语法零基础 → 能写小工具3–6 周1–2 个月变量、循环、函数、类2Pythonic

By Ne0inhk
Python 小工具实战:图片水印批量添加工具

Python 小工具实战:图片水印批量添加工具

Python 小工具实战:图片水印批量添加工具 Python 小工具实战:图片水印批量添加工具,本文详细介绍了使用 Python开发 给图片加水印的工具,该工具基于 Pillow 和 tkinter 库构建,可解决单图处理耗时、专业软件操作复杂的问题。工具支持单图与批量处理,用户能自定义水印文字、字体大小、透明度及颜色,还可选择 9 个常用水印位置或设置行列重复分布。新增的全屏水印模式可通过调整旋转角度与间距,生成铺满图片的版权保护水印,且界面采用卡片式布局,搭配浅灰背景与蓝色按钮,简洁美观,底部状态栏实时显示操作进度。文中提供完整可运行代码,并给出参数校验、字体兼容、常见报错解决等实用内容,新手按步骤即可上手,或者直接运行使用。 前言     Python作为一门简洁、易读、功能强大的编程语言,其基础语法是入门学习的核心。掌握好基础语法,能为后续的编程实践打下坚实的基础。本文将全面讲解Python3的基础语法知识,适合编程初学者系统学习。Python以其简洁优雅的语法和强大的通用性,成为当今最受欢迎的编程语言。本专栏旨在系统性地带你从零基础入门到精通Python核心。无论你是

By Ne0inhk
Python中一切皆对象:深入理解Python的对象模型

Python中一切皆对象:深入理解Python的对象模型

Python中一切皆对象:深入理解Python的对象模型 * 什么是"一切皆对象"? * Python对象的类型层次 * 1. 内置类型对象 * 2. 函数对象 * 3. 类对象和实例对象 * 4. 模块对象 * 对象行为的统一性 * 特殊方法:对象行为的背后 * 对象模型的实际应用 * 性能考虑 * 总结 Python以其"一切皆对象"的设计哲学而闻名,这种设计为语言带来了极大的灵活性和一致性。本文将深入探讨Python的对象模型,解释为什么说"Python中一切皆对象",并通过实例展示这一特性如何影响我们的编程方式。 什么是"一切皆对象"? 在Python中,从简单的数字、字符串到复杂的函数、类甚至模块,所有这些都是对象。这意味着它们都有: 1. 身份(identity):对象在内存中的唯一地址,可通过id()函数获取 2.

By Ne0inhk
Python中的“==“与“is“:深入解析与Vibe Coding时代的优化实践

Python中的“==“与“is“:深入解析与Vibe Coding时代的优化实践

🌟 Python中的"=="与"is":深入解析与Vibe Coding时代的优化实践 * 1. 🧐 `==`与`is`的本质区别 * 2. 🕵️‍♂️ `is`判断对象身份 - 数组与常量池案例 * 案例1:列表对象的身份 * 案例2:小整数常量池 * 案例3:字符串驻留 * 3. 🔍 `==`与`__eq__`魔法函数 * 4. 🔎 类型判断的正确姿势:使用`is` * 5. 🚀 Vibe Coding时代的提示词优化 * 场景1:解释概念 * 场景2:代码生成 * 场景3:调试帮助 * 📊 对比总结表 * 💡 实际应用建议 * 🌈 结语 在Python的奇妙世界中,==和is这两个看似简单的操作符常常让初学者感到困惑。它们如同双胞胎,外表相似却性格迥异。本文将带你深入探索它们的区别,并通过生动的案例和图表展示它们的应用场景,

By Ne0inhk