奇思妙想:利用野指针和lower_bound()/upper_bound()函数实现整数二分
众所周知,c++的STL中提供了三个二分查找函数,binary_search(),lower_bound(),upper_bound(),功能分别是找某值是否在数组中出现,找到数组中第一个大于等于某值的元素,找到数组中第一个大于某值的元素。
这三个函数使用十分灵活,可以通过自定义结构体,比较函数,重载大于小于号来实现各种用法,但是它们有一个共同的局限性,就是必须在数组上使用,而不能在整数上使用。
比如我要二分找一个数的向下取整的平方根,范围1e9,肯定不行,1e9的数组都开不了。
大佬的解决方法当然是手写二分辣,但是整数二分是以条件众多,难记难写著称的。所以今天开了一下脑洞,利用野指针实现整数二分。
首先我们观察lower_bound()和upper_bound()调用比较函数时的行为。
struct Example{
int index;
int num;
}exm[];
bool cmp(const Example &x,const Example &y){
printf("%d %d\n",x.index,y.index);
return x.num<y.num;
}
int main(){
for(int i=;i<=;i++){
exm[i].index=i;
exm[i].num=i;
}
Example t;
t.index=-;t.num=;
lower_bound(exm+,exm+,t,cmp);
upper_bound(exm+,exm+,t,cmp);
}
//51 -1
//26 -1
//39 -1
//45 -1
//48 -1
//50 -1
//49 -1
//-1 51
//-1 26
//-1 39
//-1 45
//-1 48
//-1 50
看出来了吧,lower_bound()在调用比较函数时,把数组元素传给比较函数的第一个参数,把待查找元素传给第二个参数
upper_bound()则相反。
自定义的比较函数对于这两个二分查找函数而言是个黑箱,只被关心返回值是几。
那么我们可以让比较函数只关心两个参数的地址,用这个地址瞎搞,不去真的访问这两个地址里面的值,比如刚才给出的例子,找平方根,可以这样写:
const int *p=;
bool cmp(const int &x,const int &y){
return (&x-p)<(&y-p)*(&y-p);
}
int main(){
int k;
scanf("%d",&k);
printf("%d",upper_bound(p+,p+k+,p[k],cmp)--p);
}
//91749281
//9578
//注意溢出
此方法的局限性:
1,指针长度有限制且无法自己定义。
#include<iostream>
#include<algorithm>
using namespace std;
int main(){
printf("the size of int* is %d\n",sizeof(int*));
printf("the size of long long is %d\n",sizeof(long long));
}
//the size of int* is 8
//the size of long long is 8
但是这个貌似没太大问题,因为所有指针,不管它指向什么,都是8位的,和long long一样长,足够了。
2,只能用于正数
指针运算没有负数,对于此种情况只能用设虚拟零点的方法解决。
3,存在非法访问的风险
目前笔者未找到任何证据能够证明二分查找函数本身不去访问指针指向的内容,有可能导致未知的非法访问。
奇思妙想:利用野指针和lower_bound()/upper_bound()函数实现整数二分的更多相关文章
- 李洪强iOS开发之【Objective-C】09-空指针和野指针
一.什么是空指针和野指针 1.空指针 1> 没有存储任何内存地址的指针就称为空指针(NULL指针) 2> 空指针就是被赋值为0的指针,在没有被具体初始化之前,其值为0. 下面两个都是空指针 ...
- 【Objective-C】4-空指针和野指针
一.什么是空指针和野指针 1.空指针 1> 没有存储任何内存地址的指针就称为空指针(NULL指针) 2> 空指针就是被赋值为0的指针,在没有被具体初始化之前,其值为0. 下面两个都是空指针 ...
- Objective-C 空指针和野指针
一.什么是空指针和野指针 1.空指针 1> 没有存储任何内存地址的指针就称为空指针(NULL指针) 2> 空指针就是被赋值为0的指针,在没有被具体初始化之前,其值为0. 下面两个都是空指针 ...
- 【Objective-C】09-空指针和野指针
一.什么是空指针和野指针 1.空指针 1> 没有存储不论什么内存地址的指针就称为空指针(NULL指针) 2> 空指针就是被赋值为0的指针.在没有被详细初始化之前.其值为0. 以下两个都是空 ...
- 【Objective-C】-空指针和野指针
一.什么是空指针和野指针 1.空指针 1> 没有存储任何内存地址的指针就称为空指针(NULL指针) 2> 空指针就是被赋值为0的指针,在没有被具体初始化之前,其值为0. 下面两个都是空指针 ...
- C++中lower_bound函数和upper_bound函数
STL中关于二分查找的函数有三个lower_bound .upper_bound .binary_search .这三个函数都运用于有序区间(当然这也是运用二分查找的前提),下面记录一下这两个函数. ...
- C语言之free函数及野指针
[FROM MSDN && 百科] 原型: void free(void *ptr); #include<stdlib.h>或#include <malloc.h& ...
- STL之std::set、std::map的lower_bound和upper_bound函数使用说明
由于在使用std::map时感觉lower_bound和upper_bound函数了解不多,这里整理并记录下相关用法及功能. STL的map.multimap.set.multiset都有三个比较特殊 ...
- lower_bound和upper_bound函数
lower_bound(ForwardIter first,ForwardIter last,const_TP & val) upper_bound(ForwardIter first,For ...
随机推荐
- ES6常用点
原文 http://es6.ruanyifeng.com/#docs 变量--------------------------------------------- 1.let声明.const声 ...
- elementUI 日期时间选择器 只能选择当前及之后的时间
日期时间选择器 只能选择当前及之后的时间 <el-date-picker class="input-border-null" prefix-icon="el-ic ...
- VC 串口通讯基本原理,讲的很是详细
目 录打开串口............................................................................................. ...
- tomcat8.5在centos部署阿里云免费证书
最近在做微信小程序,部署完服务器之后,发现报了个错误,说是我的域名不在以下合法域名列表中.对比了一下才发现我的域名还是http的没升级到https,之后我就到阿里云去申请了证书.中间有一次审核失败,查 ...
- Bootstrap-table 使用总结 转载https://www.cnblogs.com/laowangc/p/8875526.html
一.什么是Bootstrap-table? 在业务系统开发中,对表格记录的查询.分页.排序等处理是非常常见的,在Web开发中,可以采用很多功能强大的插件来满足要求,且能极大的提高开发效率,本随笔介绍这 ...
- Django框架(五)—— 虚拟环境搭建
目录 Django虚拟环境搭建 Django虚拟环境搭建 一.为什么要用虚拟环境 公司以前开发的项目是在Django1.5的基础上开发的,先要需要基于Django2.0开发一套项目.这样不能卸载原有版 ...
- python中函数的定义及调用
python中函数的定义及使用方法 1.函数的概念:函数是将具有独立功能的代码块组织为一个整体,使其具有特殊功能的代码集; 2.函数的作用:使用函数可以加强代码的复用性,提高程序编写的效率; 3.函数 ...
- HTML中列表中元素居中问题
想让列表<table>中某一行元素居中的话,单纯使用<align = 'center'>是达不到效果的,需要先将该行进行合并,使用colspan属性. <html> ...
- 第二记 Java数据类型
一.数据类型 java中数据类型分为基本数据与引用数据类型两大类,其中又有更细致的划分,下面以图展示 二.基本数据类型封装类 Java是一门面向对象的语言,但是在一些情况下基本数据类型无法满足Java ...
- python库argparse中type的新奇指定方法
最近在看一些项目的源码,总是能学到好多东西. 关于arparse中type的类型指定 不止可以指定常规类型,还可以加一些自己类型判断,具体用法如下(来源): def str2bool(v): &quo ...