upper_bound函数,binary_check函数

个人心得:二分的经典运用,刚开始就是upper_bound可能难以实现一点,还有就是要注意没找到的时候

lower_bound 返回大于等于key的第一个元素的下标。
upper_bound 返回大于key的第一个元素的下标(即小于等于key的最后一个元素的下一个元素的下标)。


设result为这两个函数的返回值。


在每次的while迭代前,result的候选范围为区间[low,high]。


初始情况:这两个函数的返回值的可能范围为[0,n](数组A的下标范围是[0,n-1])。


保持:根据A[middle]和key的比较,有3种情况:
①A[middle]=key
对于lower_bound,A[middle](及其前面的元素)可能是等于key的第一个元素,而A[middle+1]至少是等于key的第二个元素。故middle为候选result,而middle+1不是。故令high=middle。
对于upper_bound,A[middle]可能是小于等于key的最后一个元素,而A[middle]前面的元素则不可能,故它的下一个元素A[middle+1]可能是大于key的第一个元素。故令low=middle+1。


若数组A中不存在与key相等的元素,那么两个函数的result是一样的,即都是大于key的第一个元素的下标,所以在A[middle]和key不相等的情况下,对low和high的设置是一样的。
②A[middle]<key
而A[middle+1]有可能大于key,且A[middle]之前的元素不可能大于key。故令low=middle+1。
③A[middle]>key
A[middle]有可能是大于key的第一个元素,而A[middle+1]至少是第二个,且A[middle]之前的元素也可能大于key,故令high=middle。


终结:
每次区间[low,high]的长度都会至少减1。当长度减少至1时,结果就出来了。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<iomanip>
 6 #include<algorithm>
 7 using namespace std;
 8 int uppercheck(int a[],int n,int key)
 9 {
10     int i=0,j=n-1;
11     while(i<j){
12         int mid=(i+j)/2;
13         if(a[mid]>key)
14             j=mid;
15         else
16             i=mid+1;
17     }
18     if(a[i]>key)
19     return i;
20     else return -1;
21 }
22 int binarycheck(int a[],int n,int key)
23 {
24     int i=0,j=n-1;
25     while(i<=j){
26         int mid=(i+j)/2;
27         if(a[mid]==key)
28             return mid;
29         else  if(a[mid]>key)
30             j=mid-1;
31             else
32                 i=mid+1;
33     }
34     return -1;
35 }
36 int main()
37 {
38 
39     int a[15];
40     for(int i=0;i<5;i++)
41         cin>>a[i];
42     cout<<binarycheck(a,5,5)<<endl;
43     cout<<uppercheck(a,5,5)<<endl;
44     return 0;
45 }
View Code
原文地址:https://www.cnblogs.com/blvt/p/7788132.html