所在头文件:#include<algorithm>
函数分类:Binary search (operating on partitioned/sorted ranges)
函数功能:lower_bound()返回一个迭代器指针,指向val出现在这个被查找序列中出现的第一个位置;upper_bound()返回一个迭代器指针,指向val出现在这个被查找序列中出现的最后一个位置的后一个位置。
lower_bound()的函数模板功能相当于:
template <class ForwardIterator, class T>
ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last, const T& val)
{
ForwardIterator it;
iterator_traits<ForwardIterator>::difference_type count, step;
count = distance(first,last);
while (count>0)
{
it = first; step=count/2; advance (it,step);
if (*it<val) { // or: if (comp(*it,val)), for version (2) first=++it; count-=step+1; } else count=step; } return first; }
upper_bound()
的函数模板功能相当于:
ForwardIterator upper_bound (ForwardIterator first, ForwardIterator last, const T& val)
{
ForwardIterator it;
iterator_traits<ForwardIterator>::difference_type count, step;
count = std::distance(first,last);
while (count>0)
{
it = first; step=count/2; std::advance (it,step);
if (!(val<*it)) // or: if (!comp(val,*it)), for version (2)
{
first=++it; count-=step+1;
}
else count=step;
}
return first;
}
lower()返回的是有序数组中第一次出现val的位置,如果找不到,则返回数组的最后一个位置。
upper()返回的是有序数组中最后一次出现val的位置的后一个位置,如果找不到,则返回数组的最后一个位置,如果val与数组最后一个元素相等,则返回数组的最后一个位置。
upper()除了比lower()多了一个 =
以外,其它的地方完全相同。
代码中,array为要查找的数组,b为数组的起始位置,e为数组的结束位置,val为要查找的值,first为指向数组中某个位置的指针,初始化为第一个元素,count为first指针最多能移动的位数,setp为指针需要的位数。
lower()中,当array[it]比val小时,就一直移动first指针,且只向后移动一位(就是这里保证了返回val第一次出现的位置;如果是array[it]等于val,则first指针不会移动,count的值会一直减少,每次减少一半,最终等于0,循环结束然后返回first;如果是array[it]大于val,则first不会移动,count会一直缩减到使得array[it]小于等于val的大小),移动后,更新最多可移动的的位数,这个值为e与first的差,既first的右边部分。
在数组a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}中查找 7
调用lower(a, 0, 9, 7);
first = 0; count = 9;
第一次循环:
it = 0; step = 4; it = 4; a[it] = 5; first = 5; count = 4;
第二次循环:
it = 5; step = 2; it = 7; a[it] = 8; first = 6; count = 1;
第三次循环:
it = 6; step = 0; it = 6; a[it] = 7; count = 0;
找到结束。
#include <bits/stdc++.h>
using namespace std;
int lower(int *array, int b, int e, int val)//二分查找下界
{
int first = b;
int count = e - b;
while (count > 0)
{
int it = first;
int step = count / 2;
it = it + step;
if (array[it] < val)
{
first = ++it;
count = count - (step + 1);
}
else
{
count = step;
}
}
return first;
}
int upper(int *array, int b, int e, int val)//二分查找上界
{
int first = b;
int count = e - b;
while (count > 0)
{
int it = first;
int step = count / 2;
it = it + step;
if (array[it] <= val)
{
first = ++it;
count = count - (step + 1);
}
else
{
count = step;
}
}
return first;
}
int main()
{
int array[] = {0,1,2,3,4,5,5,5,5,5,6,6,6,7,8,9,10,11,11,11,12,12,13,13};
int e = sizeof(array) / sizeof(int);
int ans1 = lower(array, 0, e - 1, 11);
int ans2 = upper(array, 0, e - 1, 11);
printf("数组中第一次出现11的位置: %d\n", ans1);
printf("数组中最后一次出现11的位置的后一个位置: %d\n", ans2);
printf("------------------------------------------\n");
int ans3 = lower(array, 0, e - 1, 13);
int ans4 = upper(array, 0, e - 1, 13);
printf("数组中第一次出现13的位置: %d\n", ans3);
printf("数组中最后一次出现13的位置的后一个位置: %d\n", ans4);//此处返回数组的最后一个位置
printf("------------------------------------------\n");
int ans5 = lower(array, 0, e - 1, 100);
int ans6 = upper(array, 0, e - 1, 100);
printf("找不到 %d,返回数组的最后一个位置\n", ans5);
printf("找不到 %d,返回数组的最后一个位置\n", ans6);
printf("-------------\n");
return 0;
}