本篇谈论upper_bound函数的差别,lower_bound函数可同理。
一、数组
我们通常需要查找一个数组里第一个比x大的是多少会这样写
int a[25]={3,1,5,6};
int t;
sort(a,a+4);//1 3 5 6
int x=2;
t=upper_bound(a,a+4,x)-a; //查找下标
cout << t << endl ; //输出 1
cout << a[t] << endl ; //输出 3
我们在查找下标时,需要在函数后面-a,
t=upper_bound(a,a+4,x)-a; //查找下标
这是干嘛用的?
我们首先要知道,upper_bound函数返回的是一个指向数组中比x大的第一个数的指针,即返回的是一个指针,并不是下标。(此题中就是返回指向3的指针)
而一个数组里的地址的连续的,数组a中从0开始到最后都是一段连续的地址(地址连续并不代表地址所表现出的&p连续,只是这两个地址间不会有其他东西的地址)一个数组也是有地址的,它的地址就是第一个的地址,且能直接用这个数组的名称来表达,即a就是a数组的地址,也就是a[0]的地址。
所以,我们upper_bound函数虽然返回的是一个地址,当我们拿这个地址去减a(即减第一个的地址),得到的就是相对于第一个数,我们要求的数的相对位置,即我们得到的下标。
例如
a[0],a[1],a[2]中,a[1]相对于第一个(a[0])相对位置是1,下标就是1,a[1]的地址减去a[0]的地址得到的就是相对位置1,所以这个1可以当作我们要求的下标
总结:upper_bound函数返回的并不是下标,而是一个指针,我们将这个指针减去数组第一个数的指针就可以得到指针指向的数的下标
二、vector
我们在vector中想要查找第一个比x大的数要怎样写?
vector<int>v;
v.push_back(1);
v.push_back(3);
v.push_back(2);
v.push_back(5);
v.push_back(7);
sort(v.begin(),v.end());// 1 2 3 5 7
vector<int>::iterator it;//定义迭送器
int x=4;
it=upper_bound(v.begin(),v.end(),4);//查找第一个大于4的数,并返回它的迭送器
cout << *it << endl ; //输出迭送器的值:5
我们在数组部分已经讲清楚了upper_bound函数到底是怎么进行操作的,在vector中,我们也可以类比过来。
迭送器相当于一个指针,所以我们在接收upper_bound函数返回值前要先定义一个迭送器,来接收upper_bound的返回值(这里我们可以把迭送器就看作的指针)我们输出这个值的时候就可以直接像输出指针的值。
vector也是可以通过下标来访问的,我们可不可以像数组一样找到下标t,再输出其值呢?当然也是可以的
我们需要注意,同样是用一个指针减去第一个数的指针。
数组中可以直接用数组的名称来当作这个数组中第一个数的地址
然后vector中不能这样操作
我们减去的必须就写成第一个数的指针(迭送器),即-v.begin()
vector<int>v;
v.push_back(1);
v.push_back(3);
v.push_back(2);
v.push_back(5);
v.push_back(7);
sort(v.begin(),v.end());// 1 2 3 5 7
int t;
t=upper_bound(v.begin(),v.end(),4)-v.begin();
// 第一个大于4的迭送器与容器中第一个数的迭送器做差
cout << t << endl ; // 输出 3
cout << v[t] << endl ; // 输出 5
但是!!!
这样也非常不安全的
因为vector的容积非常大,不一定能满足所以的元素所在的地址是相连的,所以这样求出来的下标有时候并不准确,不建议这样使用
三、set
set中我们怎么写呢?和vector几乎一样
set<int>s;
s.insert(1);
s.insert(3);
s.insert(5);
s.insert(7);
s.insert(9);
set<int>::iterator it;//定义迭送器
int x=6;
it=upper_bound(s.begin(),s.end(),x); //查找第一个大于x的元素的迭送器
cout << *it << endl ; //输出迭送器所对应的值 7
但是,set对我们挺友好的,它直接向我们提供了在它整个set里寻找此类x的函数。所以如果我们是在整个set里查找的话,可以直接这样写
set<int>s;
s.insert(1);
s.insert(3);
s.insert(5);
s.insert(7);
s.insert(9);
set<int>::iterator it;//定义迭送器
int x=6;
it=s.upper_bound(x); //查找第一个大于x的元素的迭送器
cout << *it << endl ; //输出迭送器所对应的值 7