c++stl之lower_bound,upper_bound和equal_range函数的详细介绍!!!

Posted 大忽悠爱忽悠

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c++stl之lower_bound,upper_bound和equal_range函数的详细介绍!!!相关的知识,希望对你有一定的参考价值。


lower_bound,upper_bound和equal_range函数初识

lower_bound.(k)返回一个迭代器,指向第一个值不小于k的元素
upper_bound(k)返回一个迭代器,指向第一个值大于k的元素
equal_range(k)返回一个迭代器pair,表示值等于k的元素的范围。若k不存在,pair两个成员均等于end()–尾迭代器
  • 上面三个函数多用于容器中使用,但是对于普通的数组也是可以使用的,下面会讲到.
  • 如果所查找值在容器中,lower_bound返回的迭代器将指向第一个具有给定值的元素而upper_bound返回的迭代器指向最后一个匹配给定值的元素之后的位置
  • 如果元素不在容器中,则lower_bound和upper_bound会返回相等的迭代器----指向一个不影响排序的值插入位置
  • 因此,用相同的值调用lower_bound和upper_bound会得到一个迭代器的范围,表示具有该关键字的元素范围。
  • 当然,这两个操作返回的迭代器可能是容器的尾后迭代器。如果我们查找的元素具有容器中最大值,则此关键字的upper_bound返回尾后迭代器。如果关键字不存在,且大于容器中任何关键字,则lower_bound返回的也是尾后迭代器.

注意事项

  • lower_bound返回的迭代器可能指向一个具有给定值的元素,但也可能不指向。
  • 如果关键字不在容器中,则lower_bound会返回关键字的第一个安全插入点—不影响容器中元素顺序的插入位置
  • 如果lower_bound和upper_bound返回相同的迭代器,则给定的关键字不在容器中.

具体使用说明

  • 1.与map容器结合使用,打印map容器中作者英文名字对应为Tom的所有出版书籍.
void test()
{
	//注意map容器不能插入重复关键字
	map<string, string> author = {
		{"Jerry","Jerry's travel"},
		{"Boboy","Star Star Star"},
		{"Tom","I Love Mouse"},
	};
	for (auto beg = author.lower_bound("Tom"), end = author.upper_bound("Tom"); beg != end; beg++)
		cout << beg->second << endl;
}

在这里插入图片描述

  • 2.与vector结合使用,打印vector数组中大于等于5的元素范围
	//这里数组v最好是有序的
	vector<int> v = { 1,2,3,4,5,6,7,8 };
	for (auto beg = lower_bound(v.begin(), v.end(),5); beg != v.end(); beg++)
		cout << *beg <<" " <<ends;
	cout << endl;

在这里插入图片描述

注意:数组最好是有序的,不然打印范围是错误的

  • 3,在vector数组中查找存在的元素2

注意:数组必须是有序的,不然查找结果会出错

	//这里数组v最好是有序的
	vector<int> v = { 1,2,3,4,5,6,7,8};
	auto beg = lower_bound(v.begin(), v.end(), 5), end = upper_bound(v.begin(), v.end(), 5);
		cout << *beg <<" " <<ends;
		cout << endl<<*end << endl;
	cout << endl;

在这里插入图片描述
注意观察这里beg和end查找到的对应值区别,beg从前往后找到第一个大于等于对应值的元素,而end从后往前查找第一个大于对应值的元素。

  • 4,在vector数组中查找不存在的元素

1.如果查找的不存在元素是4

	//这里数组v最好是有序的
	vector<int> v = { 1,2,3,5,6,7,8};
	auto beg = lower_bound(v.begin(), v.end(), 4), end = upper_bound(v.begin(), v.end(), 4);
	if (beg == v.end())
		cout << "beg此时指向尾迭代器" << endl;
	else
		cout << *beg << endl;
	if (end == v.end())
		cout << "end此时指向尾迭代器" << endl;
	cout << *end << endl;
	cout << endl;

在这里插入图片描述
2.如果查找的不存在元素是8
在这里插入图片描述
3.如果查找的不存在元素是10
在这里插入图片描述

  • 4,利用equal_range函数打印map容器中所有关键字为2的元素
void test()
{
	multimap<int, int> map = {
		{1,0},
		{1,520},
		{2,4},
		{2,3},
		{2,6},
		{4,5},
		{7,8},
		{10,22},
	};
	for (auto beg = map.lower_bound(2), end = map.upper_bound(2); beg!= end; beg++)
		cout << beg->second << endl;
}

在这里插入图片描述


equal_range函数使用注意事项

  • 此函数接受一个关键字,返回一个迭代器pair。

  • 若关键字存在,则第一个迭代器指向第一个与关键字匹配的元素,第二个迭代器指向最后一个与关键字匹配的元素之后的位置。

  • 若未找到匹配元素,则两个迭代器都指向关键字可以插入的位置.

  • 其实equal_range返回的pair,此pair的first成员保存的迭代器与lower_bound返回的迭代器是一样的,second保存的迭代器与upper_bound的返回值是一样的。


高级用法

这里先介绍一种高级用法,用lower_bound来简化二分查找算法的写法:

  • 这里顺便也补上lower_bound函数与普通数组结合使用的案例
bool BS(int* arr,int val)
{
	auto pos=lower_bound(arr, arr + 8, val);
	if (*pos== val)
		return true;
	return false;
}
int main()
{
	int arr[8] = { 1,2,3,4,5,6,7,8 };
	cout << "查找指定元素4是否在数组中" << endl;
	if (BS(arr, 4))
		cout << "查找到指定元素" << endl;
	else
		cout << "没有此元素" << endl;
	return 0;
}

在这里插入图片描述
在这里插入图片描述

以上是关于c++stl之lower_bound,upper_bound和equal_range函数的详细介绍!!!的主要内容,如果未能解决你的问题,请参考以下文章

stl map中的lower_bound和 upper_bound

upper_bound()和lower_bound()操作,stl库

upper_bound()和lower_bound()操作,stl库

stl(GCC4.9.3 in MinGW)中rbtree lower_bound/upper_bound 的实现

徒手实现lower_bound和upper_bound

STL之二分查找 (转载)