终极二分查找--传说十个人写九个有bug
之前写过一篇极为罗嗦的二分查找,非常得意地以为以后就可以避免踩坑了,但是今天才知道二分查找可以写的既简洁又鲁棒,唉!还是要多学习啊!
给一个按照从大到小的顺序排序好的数组a[]={1,2,3,4,7,7,7,8,9,10};
用二分查找分别求等于4,大于7的第一个数,大于等于7的第一个数,小于7的最大的数,小于等于7的最大的数。
如果写的不小心的话非常容易陷入死循环,有的时候写二分可能也会面临是l = mid还是l=mid+1这样的纠结,所以本文要证明,这几种查询的方式是可以
统一在一起的,只需要重载元素的小于号,就可以完成所有的工作
#include <bits/stdc++.h>
using namespace std;
int n;
int a[] = {,,,,,,,,,};//以升序列为例,降序也一样道理 bool cmp(int x,int v)
{
return x < v;//判断a[mid]和所要查找的边界值的关系,
//我们只需要一个小于号就可以表示出大于,等于,小于,大于等于,小于等于,这也是为什么在sort里面需要重载小于号即可。
} int b_search(int a[],int n,int v)//精确查找数组里是不是有等于v的元素
{
int l = -,r = n;//把l,r预先设定成两个边界值,在查找大于小于的时候非常有用,下面再说。
for(int mid;r-l>;){//强烈建议多用for,少用while
mid = (l+r)>>;
if(!cmp(a[mid],v)&&!cmp(v,a[mid])) return mid;//如果a【mid】不小于v,反之也不成立,只能是相等了,直接返回地址
else if(cmp(a[mid],v)) l = mid+;//a【mid】小于v此时a[mid]在v的右边,所以查找区间应该右移
else r = mid-;//反之同理
}
if(a[l] == v) return l;//如果最后得到的地址的值确实等于要查找的值,返回地址。
else return -;//否则,返回-1
} int upperequal(int a[],int n,int v)//大于等于v的最小的数,相当于stl的lower_bound函数
{
int l = -,r = n;//这里有一个隐含的意思是l是小于v的,r是大于v的那个元素,一直保持这样就可以不陷入死循环
for(int mid;r-l>;){
mid = (l+r)>>;
if(!cmp(a[mid],v)) r = mid;//注意这里判断的是a【mid】是不是大于等于v,
else l = mid;
}
return r;//因为r在变化过程中一直是大于等于v的,所以r就是答案
}
int upper(int a[],int n, int v)//二分查找大于v的第一个数,相当于stl里面的upperbound
{
int l = -,r = n;
for(int mid; r-l>;){
mid = (l+r)>>;
if(cmp(v,a[mid])) r = mid;
else l = mid;
}
return r;
}
int lower(int a[],int n, int v)//查找小于v的最大的元素
{
int l = -,r = n;
for(int mid; r-l>;){
mid = (l+r)>>;
if(cmp(a[mid],v)) l = mid;
else r = mid;
}
return l;
}
int lowerequal(int a[],int n, int v)查找小于等于v的最大的元素
{
int l = -,r = n;
for(int mid;r-l>;){
mid=(l+r)>>;
if(!cmp(v,a[mid])) l = mid;
else r = mid;
}
return l;
}
int main()
{
cout<<lowerequal(a,,)<<endl;
}
相信再也不会担心死循环了
终极二分查找--传说十个人写九个有bug的更多相关文章
- POJ 1064 Cable master(二分查找+精度)(神坑题)
POJ 1064 Cable master 一开始把 int C(double x) 里面写成了 int C(int x) ,莫名奇妙竟然过了样例,交了以后直接就wa. 后来发现又把二分查找的判断条 ...
- 二分查找(Java实现)
二分查找:递归实现 public class BinarySearch { /** * @param arr 代查找的数组,需要有序 * @param left 查找区间的左界限 * @param r ...
- 面试官,我会写二分查找法!对,没有 bug 的那种!
前言科普 第一篇二分搜索论文是 1946 年发表,然而第一个没有 bug 的二分查找法却是在 1962 年才出现,中间用了 16 年的时间. 2019 年的你,在面试的过程中能手写出没有 bug 的二 ...
- 九度OJ 1349 数字在排序数组中出现的次数 -- 二分查找
题目地址:http://ac.jobdu.com/problem.php?pid=1349 题目描述: 统计一个数字在排序数组中出现的次数. 输入: 每个测试案例包括两行: 第一行有1个整数n,表示数 ...
- C++11写算法之二分查找
同样的,二分查找很好理解,不多做解释,要注意二分查找的list必须是排好序的. 这里实现了两种二分查找的算法,一种递归一种非递归,看看代码应该差不多是秒懂.想试验两种算法,改变一下findFunc函数 ...
- 浅谈算法和数据结构: 七 二叉查找树 八 平衡查找树之2-3树 九 平衡查找树之红黑树 十 平衡查找树之B树
http://www.cnblogs.com/yangecnu/p/Introduce-Binary-Search-Tree.html 前文介绍了符号表的两种实现,无序链表和有序数组,无序链表在插入的 ...
- leetcode二分查找问题整理
自从做完leetcode上的三道关于二分查找的题后,我觉得它是比链表找环还恶心的题,首先能写出bugfree代码的人就不多,而且可以有各种变形,适合面试的时候不断挑战面试者,一个程序猿写代码解决问题的 ...
- 二分查找实现(Jon Bentley:90%程序员无法正确实现)
二分查找实现(Jon Bentley:90%程序员无法正确实现)作者:July出处:结构之法算法之道引言Jon Bentley:90%以上的程序员无法正确无误的写出二分查找代码.也许很多人都早已听说过 ...
- 分蛋糕(C - 二分查找)
分蛋糕 题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=85904#problem/C Description My birthd ...
随机推荐
- UVa 1366 - Martian Mining (dp)
本文出自 http://blog.csdn.net/shuangde800 题目链接: 点击打开链接 题目大意 给出n*m网格中每个格子的A矿和B矿数量,A矿必须由右向左运输,B矿必须由下向上运输 ...
- android后台截屏实现(2)--screencap源码修改
首先找到screencap类在Android源码中的位置,/442/frameworks/base/cmds/screencap/screencap.cpp 源码如下: /* * Copyright ...
- uvalive 4851 Restaurant(扫描法)
题意:有一个M*M的网格,坐标[0...M-1,0...M-1] 网格里面有两个y坐标同样的宾馆A和B.以及n个餐厅,宾馆AB里面各有一个餐厅,编号1,2,其它餐厅编号3-n.如今你打算新开一家餐厅. ...
- MyEclipse 8.0注冊码+原版下载_Java开发软件
MyEclipse是一个十分优秀的用于开发Java, J2EE的Eclipse插件集合,MyEclipse的功能很强大,支持也十分广泛,尤其是对各种开元产品的支持十分不错.MyEclipse眼下支持J ...
- mvc中使用jsonp进行跨域请求详细说明
在web开发中,如果你要在不同域下进行数据异步请求,会出现一个No ‘Access-Control-Allow-Origin’ header is present on the requested r ...
- .NET基础拾遗(7)多线程开发基础1
一.多线程编程的基本概念 1.1 操作系统层面的进程和线程 (1)进程 进程代表了操作系统上运行着的一个应用程序.进程拥有自己的程序块,拥有独占的资源和数据且可以被操作系统调度. But,即使是同一个 ...
- HTML1.0 - html 环境搭建 开发工具
1. mac 电脑 2. Hbuilder 开发软件 3. 学习基础 HTML 语法 网站 http://www.w3school.com.cn
- Beacon浅析
作者:hongbosun 一.Beacon简介 Beacon是基于BLE技术实现的物理设备.BLE(全称Bluetooth Low Energy)是蓝牙4.0技术规范的一部分.它起源于Nokia的Wi ...
- (转).NET平台开源JSON库LitJSON的使用方法
一个简单示例: String str = "{’name’:’cyf’,’id’:10,’items’:[{’itemid’:1001,’itemname’:’hello’},{’itemi ...
- JavaScript和ajax 跨域的案例
今天突然想看下JavaScript和ajax 跨域问题,然后百度看了一下,写一个demo出来 <!DOCTYPE html> <html xmlns="http://www ...