C++ binary_serarch() lower_bound() upper_bound() 用法

 

目录

1.binary_search(arr+n1,arr+n2,value)

2.lower_bound(arr+n1,arr+n2,value)

3.upper_bound(arr+n1,arr+n2,value)

手写lower_bound(), upper_bound()


1.binary_search(arr+n1,arr+n2,value)

2.lower_bound(arr+n1,arr+n2,value)

3.upper_bound(arr+n1,arr+n2,value)


 

头文件:#include <algorithm>

1.binary_search(arr+n1,arr+n2,value)

	int arr[] = {2,3,4,5,6};
	int t = binary_search(arr,arr+5,3);
	cout << t << endl;

   查找区间是[l,r) 左闭右开区间,即arr[0]至arr[4].

   查找元素为3, 输出结果为1,

查找成功返回1,查找失败返回0

2.lower_bound(arr+n1,arr+n2,value)

   返回值为一个指针  T * p;

   p指向  查找>=value下标最小的元素,若找不到,p指向下标为n2的元素

	int arr[] = {2,3,3,4,4,5,6};
	int* p = lower_bound(arr,arr+7,4);
	cout << p-arr << endl;  //输出下标为3

p指向第一个4,p-arr的值为3,即第一个4的下标

若要想直接查找下标可以这样写  int pos = lower_bound(arr,arr+7,4)-arr;        pos等于3,  arr[pos]等于4

若查找一个不存在的元素

	int arr[] = {2,3,3,4,4,5,6};
	int* p = lower_bound(arr,arr+7,7);
	cout << p-arr << endl;  //输出下标

p指向arr[7] (不存在),因为数组arr最后一个元素为arr[6]

p-arr为7,这样也可以判断是否查找失败

3.upper_bound(arr+n1,arr+n2,value)

返回值为一个指针  T* p

*p是指向查找比value大且下标最小的元素,若找不到,p指向下标为n2的元素。

注意区别lower_bound()是 >=,  upper_bound()只能是大于

 int arr[] = {2,3,3,4,4,5,6}; 

 int* p = lower_bound(arr,arr+7,4);  p指向的是第一个4

int* p = upper_bound(arr,arr+7,4);  p指向的是5

看下面例子:

    int arr[] = {2,3,3,4,4,5,6};
	int* p = upper_bound(arr,arr+7,3);
	cout << p-arr << endl;  //输出下标

p-arr 即p指向元素的下标为:3    , 即为第一个4

当使用upper_bound查找一个不存在的元素,同理,p指向arr[7],不存在, p-arr为7

 

 

 

手写lower_bound(), upper_bound()

 

// 查找>=value下标最小的元素
int myLower_bound(int arr[],int l,int r,int target){
	//idx == 数组最后元素下标的后一个指针
	//若target比数组里面的值都大,则idx不变
	int idx = r+1;
	while(l <= r){
		int mid= (l+r)>>1;
        // trget 在 nums[mid]左边, 此时的mid是符合要求的,但不是最小的
        // 二分缩小空间,一定能找到 >= target 且idx是最小的
        //相等的值不要考虑,所以相等的值,要向左边缩小
		if(target <= arr[mid]){ 
			idx = mid;
			r = mid-1;
		}
		else l = mid+1;
	}
	return idx;
}

//value大且下标最小的元素
int myUpper_bound(int arr[],int l,int r,int target){
	int idx = r+1;
	while(l <= r){
		int mid = l + (r-l)/2;
        //target在arr[mid]的左边,mid符合要求,但不是最小的
        //二分查找可以缩小空间,直到mid大于target且最小
		if(target < arr[mid]){ 
			r = mid-1;
			idx = mid;
		} 
		if(target >= arr[mid]){ //在相等时,要往右边缩小,相等的值不考虑
			l = mid+1;
		} 
	}
	return idx;
}

 

总的来说,upper_bound()和lower_bound();

关键的两个因素:

1. idx 在什么条件下,取得? 因为无论是lower_bound()还是upper_bound(), 都是需要找比 target大或者相等的下标,所以 在 target < or <= nums[mid] ,中取得 mid的值,mid的值>= target

2. 在target 与 nums[mid]相等是,l,r该往那边缩小?

     lower_bound因为nums中的值和target相同时,也可以,同时相同的值得下标也要求最小,所以向左边缩小

    upper_bound不考虑相同的值,所以,相同时往缩小,忽略相同的值

 

 

逆向lower_bound()

 

int main(int argc, char const *argv[]){
	int arr[] = {10,9,8,6,3,2,2,2,1,0};

	//找比target大或相等(下标最大)的值
	int target = 2222;
	int l = 0,r = 10-1;
	int idx = 0;
	while(l <= r){
		int mid = (l+r)/2;
		if(target < arr[mid]) l = mid+1;
		//相等时,取最右边的值,向右边收缩
		if(target == arr[mid]){
			idx = mid;
			l = mid + 1; 
		}
		if(target > arr[mid]) r = mid-1;
	}
	cout << idx << endl;

}

 

在Java中,没有直接提供lower_boundupper_bound函数,但可以通过使用Collections类的binarySearch方法来实现类似的功能。 1. lower_bound函数: lower_bound函数用于在有序数组中查找第一个大于等于给定值的元素的位置。在Java中,可以使用Collections类的binarySearch方法来实现lower_bound函数。binarySearch方法返回的是要查找元素的索引,如果找到了该元素,则返回其索引;如果没有找到,则返回一个负数,表示该元素应该插入的位置的负数形式。 下面是一个示例代码: ```java import java.util.ArrayList; import java.util.Collections; public class Main { public static void main(String[] args) { ArrayList<Integer> list = new ArrayList<>(); list.add(1); list.add(2); list.add(3); list.add(3); list.add(4); list.add(5); int target = 3; int index = Collections.binarySearch(list, target); if (index < 0) { index = -index - 1; } System.out.println("lower_bound: " + index); } } ``` 输出结果为:lower_bound: 2 2. upper_bound函数: upper_bound函数用于在有序数组中查找第一个大于给定值的元素的位置。同样地,在Java中,可以使用Collections类的binarySearch方法来实现upper_bound函数。不过需要对返回的索引进行一些处理。 下面是一个示例代码: ```java import java.util.ArrayList; import java.util.Collections; public class Main { public static void main(String[] args) { ArrayList<Integer> list = new ArrayList<>(); list.add(1); list.add(2); list.add(3); list.add(3); list.add(4); list.add(5); int target = 3; int index = Collections.binarySearch(list, target); if (index >= 0) { index++; } else { index = -index - 1; } System.out.println("upper_bound: " + index); } } ``` 输出结果为:upper_bound: 4
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值