std::lower_bound()和std::upper_bound()总结

  今天看到了这std::lower_bound()和std::upper_bound()这两个函数,忘了它们用法,查询了相关资料并总结一下:

   1、std::lower_bound()的函数原型为  lower_bound (ForwardIterator first, ForwardIterator last,const T& val) ,它返回第一个不小于val的迭代器,而元素间比较函数为 operator<()

   2、std::upper_bound()的函数原型类似,也是upper_bound (ForwardIterator first, ForwardIterator last, const T& val) ,它返回第一个大于val的迭代器。

两者都在<algorithm>中包含

下面给个Exmaple:

#include <iostream>     
#include <algorithm>    
#include <vector>       

int main()
{
	int myints[] = { 10, 20, 30, 30, 20, 10, 10, 20 };
	std::vector<int> v(myints, myints + 8);           

	std::sort(v.begin(), v.end());               // 经过排序此时的vector中的元素为[10 10 10 20 20 20 30 30]

	std::vector<int>::iterator lower, upper;
	lower = std::lower_bound(v.begin(), v.end(), 20); 
	upper = std::upper_bound(v.begin(), v.end(), 20); 

	std::cout << "lower_bound is " << *lower << '\n'; //lower为第一个20
	std::cout << "upper_bound is " << *upper << '\n';//upper为倒数第二个30

	return 0;
}


<think>首先,用户的问题是关于C++标准库函数std::lower_bound的作用及使用方法。他们想了解其功能使用示例。 我需要注意系统级指令: - 所有行内数学表达式使用$...$格式。 - 独立公式使用$$...$$格式并单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 在回答中引用的段落末尾自然地添加引用标识,例如[^1]。 用户可见层的要求: - 回答结构清晰,帮助用户逐步解决问题。 - 尽量保证回答真实可靠。 参考的站内引用: - 引用[1]: 提供了std::lower_bound的示例代码。 - 引用[2]: 解释了std::lower_boundstd::upper_bound的功能效率。 - 引用[3]: 给出了函数模板定义。 我的回答应该基于这些引用,但需要用自己的话组织,并确保真实可靠。 结构清晰的回答: 1. 介绍std::lower_bound的功能。 2. 解释其工作原理。 3. 提供使用示例(基于引用[1]的代码)。 4. 可能添加一些注意事项或常见用法。 5. 最后生成相关问题。 使用中文回答。 在回答中,如果有引用,添加引用标识。例如,在解释功能时,引用[2];在提供示例时,引用[1]。 数学表达式:如果提到时间复杂度,使用行内数学格式,如$O(\log n)$。 独立公式:如果有公式,使用$$...$$,但这里可能不需要,除非有数学公式。 生成相关问题:在回答结束时,添加"相关问题"部分。 现在,规划回答结构: 1. **引言**:简要介绍std::lower_bound是什么。 2. **功能**:详细解释其作用,基于引用[2]。 3. **使用方法**:解释参数返回值。 4. **示例代码**:提供并解释引用[1]中的代码。 5. **注意事项**:如容器必须有序等。 6. **相关问题**:生成2-3个相关问题。 确保LaTeX正确:例如,时间复杂度写成$O(\log n)$。 相关问题示例: 1. std::lower_boundstd::upper_bound有什么区别? 2. 如何自定义比较函数使用std::lower_bound? 3. std::lower_bound在无序容器中能使用吗? 基于引用[2],它们提到了两者的区别,所以第一个问题自然。 最后,添加引用标识。</think>### C++ std::lower_bound 函数的功能及使用方法 std::lower_bound 是 C++ 标准库中的一个高效算法函数,用于在已排序的序列中查找目标值的位置。它在 `<algorithm>` 头文件中定义,通常用于有序容器如 `std::vector`、`std::array` 或普通数组。下面我将逐步解释其功能、原理使用方法,并提供详细示例。 #### 1. **功能与作用** std::lower_bound 的主要功能是**查找第一个不小于目标值(即大于或等于目标值)的元素位置**。这意味着: - 如果目标值存在于序列中,函数返回指向该值的第一个出现位置的迭代器。 - 如果目标值不存在,函数返回指向第一个大于目标值的元素的迭代器(即目标值应插入的位置)。 - 如果序列中所有元素都小于目标值,函数返回序列的尾后迭代器(如 `end()`)。 时间复杂度为 $O(\log n)$,因为它基于二分查找算法实现,要求序列必须已排序[^2]。这使得它非常适合大数据量的高效查询。 #### 2. **函数原型** 根据 C++ 标准,std::lower_bound 的函数模板定义如下: ```cpp template< class ForwardIt, class T > ForwardIt lower_bound( ForwardIt first, ForwardIt last, const T& value ); ``` - **参数**: - `first` `last`:表示序列范围的迭代器(左闭右开区间 `[first, last)`)。 - `value`:要查找的目标值。 - **返回值**:指向第一个不小于 `value` 的元素的迭代器。如果未找到,返回 `last`[^3]。 #### 3. **使用示例** 以下是一个完整的代码示例,演示了 std::lower_bound 的实际应用。该示例基于引用[1]提供的代码,并添加了详细注释: ```cpp #include <iostream> #include <algorithm> #include <vector> int main() { // 步骤1: 定义一个已排序的整数序列 std::vector<int> numbers = {1, 3, 5, 7, 9, 11, 13}; // 容器必须有序 // 步骤2: 设置目标值 int target = 7; // 步骤3: 使用 std::lower_bound 查找目标值 // 在 [begin(), end()) 范围内查找第一个不小于 target 的元素 auto it = std::lower_bound(numbers.begin(), numbers.end(), target); // 步骤4: 检查结果 if (it != numbers.end() && *it == target) { // 找到目标值,输出位置(索引从0开始) std::cout << "目标值 " << target << " 在容器中找到,位置为:" << std::distance(numbers.begin(), it) << std::endl; } else { // 未找到目标值,输出插入位置(如果需插入,应在此位置) std::cout << "目标值 " << target << " 不在容器中。" << " 可插入的位置为:" << std::distance(numbers.begin(), it) << std::endl; } return 0; } ``` - **输出解释**: - 当 `target = 7` 时,输出:`目标值 7 在容器中找到,位置为:3`(因为 7 在索引 3 处)。 - 如果 `target = 6`(不存在),输出:`目标值 6 不在容器中。可插入的位置为:3`(因为 6 应插入在 5 7 之间)。 - **关键点**: - 序列必须**有序**,否则行为未定义。 - 使用 `std::distance` 计算索引,便于输出位置信息[^1]。 #### 4. **注意事项** - **排序要求**:序列必须按升序排序。如果使用自定义类型,需提供比较函数(例如,通过重载 `operator<` 或传递谓词参数)。 - **与 std::upper_bound 的区别**:std::lower_bound 返回第一个 **不小于** 目标值的位置,而 std::upper_bound 返回第一个 **大于** 目标值的位置。两者常结合使用来查找目标值的范围[^2]。 - **性能**:在随机访问迭代器(如 `std::vector`)上效率最高,时间复杂度为 $O(\log n)$;在双向迭代器(如 `std::list`)上可能降为 $O(n)$。 #### 5. **扩展应用** std::lower_bound 不仅用于查找,还常用于插入排序或维护有序容器。例如,在实现优先级队列时,可以用它来高效插入元素: ```cpp std::vector<int> sorted_vec = {1, 2, 4, 5}; int new_val = 3; auto pos = std::lower_bound(sorted_vec.begin(), sorted_vec.end(), new_val); sorted_vec.insert(pos, new_val); // 插入后序列保持有序 ``` 通过以上步骤,您应该能掌握 std::lower_bound 的核心用法。如需进一步优化或自定义比较逻辑,可参考 C++ 文档。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值