ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

二分查找

2020-11-30 10:35:53  阅读:171  来源: 互联网

标签:二分 arr int cmp 查找 key left size


有人说,90%的程序员都手写不出正确的二分查找

没错,我就是那90%

c++的标准库里只提供了binary_search(),lower_bound(),upper_bound()三个函数,缺点就是,只能在数组或者vector这样的线性数据结构上二分

所以就需要整理一下二分的用法和代码

1,binary_search(arr[],arr[]+size,key,cmp)

功能:找到正好等于key的元素,成功则返回位置,否则返回数组末尾指针

注意,给出的最后一个参数是比较函数的指针,如果不给出,默认调用标准库中的less()函数,其实就是小于号。

这个是最好写的,不需要考虑左右边界或者失配的问题

(伪)代码:

int binary_search(arr[],arr[]+size,key,cmp) {
    int left = 0; 
    int right = nums.length - 1;
    while(left <= right) {
        int mid = (right + left) / 2;
        if(equal(arr[mid],key))
            return arr[]+mid; 
        else if (less(nums[mid],target))
            left = mid + 1;
        else 
            right = mid - 1;
        }
    return arr[]+size;
}

2,lower_bound(arr[],arr[]+size,key,cmp)

这个函数的功能是找出第一个大于等于key的值,可以简记为左边界,和上一个函数不同的是,除非key值大于全部数组中的值,才会返回arr[]+size,否则一定会返回一个有效值。

(伪)代码:

int lower_bound(arr[],arr[]+size,key,cmp){
    int left = 0;
    int right = size-1;
    while (left <= right) {
        int mid = (left + right) / 2;
        if(less(arr[mid],key)){
            left = mid + 1;
        }
        else{
            right = mid - 1;
        }
    }
    return arr[]+left;
}

注意,这个函数就比上一个难写很多,比如left,right为什么要小于等于,最后要返回的是left还是right,等等

3,upper_bound(arr[],arr[]+size,key,cmp)

这个函数的功能是找出大于key的第一个值的位置,简称右边界

int upper_bound(arr[],arr[]+size,key,cmp){
    int left = 0;
    int right = size-1;
    //查找第一个大于key的元素 
    while (left <= right) {
        int mid = (left + right) / 2;
        if (less(key,a[mid])) {
            right = mid - 1;
        }
        else {
            left = mid + 1;
        }
    }
    return arr[]+left;
}

这个函数常用于给整数开平方根,因为大于key的第一个值,减去1,就是小于等于key的最后一个值

涉及到给整数开平方根或者类似的操作的,一定记得用二分,不要自作聪明求解析解,然后转换成double,在cmath库里的函数求解,再转换回来,绝对不要!

我是不会告诉你我被昨晚的atcoder arc的B题卡了一个多小时的,天知道,1e18的数据范围,他是怎么想到构造出卡掉double+sqrt的数据的

参考资料:

https://www.cnblogs.com/kyoner/p/11080078.html

标签:二分,arr,int,cmp,查找,key,left,size
来源: https://www.cnblogs.com/isakovsky/p/14059913.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有