lower_bound算法返回第一个大于等于给定值所在的位置。设置两个指针start和last,其中start指向数组的起始位置,last指向数组末尾位置之后的位置。当start和last指向相同位置时循环结束。mid指向[start,last)区间的中间位置,当中间位置元素值大于等于给定val时,说明第一个大于等于val值在mid位置的左边,更新last为mid。当中间位置元素值小于给定的val时,说明第一个大于等于val值在mid右边,不包括mid所在的位置。更新start为mid+1。
 

int myLowerBound(vector<int> &data, int k)
{
int start = 0;
int last = data.size();
while (start < last)
{
int mid = (start + last) / 2;
if (k > data[mid]) start = mid + 1;
else last = mid;
}
return start;
}

    upper_bound算法返回第一个大于给定元素值所在的位置,设置两个指针start和last,其中start指向数组的起始位置,last指向数组末尾位置之后的位置,当start和last指向相同位置时循环结束,mid指向[start,last)区间的中间位置,当中间位置元素值小于等于给定val时,说明第一个大于val值在mid位置的右边更新start为mid+1。当中间位置元素值大于给定元素时,说明第一大于在mid左边,包括mid所在位置,所以更新last为mid。

int myUpperBound(vector<int> &data, int k)
{
int start = 0;
int last = data.size();
while (start < last)
{
int mid = (start + last) / 2;
if (k >= data[mid]) start = mid + 1;
else last = mid;
}
return start;
}

以上都是,左端是满足值。特点就是都是l永远都是=mid+1,r永远都是=mid

下面再来一发,右端是满足值的(至于是lower还是upper,就看ok函数中加不加等号就可以了):(找一个特例,比如只有两个值的模拟一下)

while(l<r) {
m=(l+r+1)/2;
if(ok()) l=m;
else r=m-1;
}
printf("l = %d\n",l);

 等价于:(左端满足值的就是在else中ans=m就可以了,比较好实现)

while(l<=r) {
m=(l+r)/2;
if(ok()) l=m+1,ans=m;
else r=m-1;
}
printf("ans = %d\n",ans);

关于binarysearch ​

upper_bound再来一种实现:

int Search(int num,int low,int high)
{
int mid;
while(low<=high)
{
mid=(low+high)/2;
if(num>=b[mid]) low=mid+1;
else high=mid-1;
}
return low;
}

纪念编辑时间:2018.10.08  10:12:42

给不会调用C++STL库中二分函数lower_bound,upper_bound,binary_search同学的一些话!_数组