奇思妙想:利用野指针和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 ...
随机推荐
- mac终端命令--自动补全
1.打开nano编辑器 输入命令 nano .inputrc,回车,打开nano编辑器 2.在nano编辑器中输入如下命令: set completion-ignore-case on set sho ...
- js 实时计算文本框字数限制
$.fn.myTarea = function(){ return this.each(function(){ $(this).bind('input propertychange', functio ...
- Windows NtQueryInformationProcess()
{ https://www.orcode.com/article/Processes_20126324.html } { 或代码 文章 编程通用 线程,进程及IPC 与NtQueryInformati ...
- springcolud依赖
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot ...
- 启动php-fpm和nginx
/usr/local/php/sbin/php-fpm #手动打补丁的启动方式/usr/local/php/sbin/php-fpm start sudo /usr/local/nginx/nginx ...
- 深入浅出 Vue.js 第九章 解析器---学习笔记
本文结合 Vue 源码进行学习 学习时,根据 github 上 Vue 项目的 package.json 文件,可知版本为 2.6.10 解析器 一.解析器的作用 解析器的作用就是将模版解析成 AST ...
- 数论+乱搞——cf181B
/* 2-type B|D^k 3-type B|D-1 11-type B|D+1 6-type B质因子分解, 7-type 其他情况 3-type: (a*(D^4-1)+b*(D^3-1)+. ...
- (转)OpenFire源码学习之十二:HttpBind&Script Syntax
转:http://blog.csdn.net/huwenfeng_2011/article/details/43417343 HttpSessionManager 该类管理所有通过httpbing连接 ...
- vc/atlmfc/include/afx.h(24) : fatal error C1189: #error : Building MFC application with /MD[d] (CRT
环境:win7,64位,vs2012 1> c:/program files/microsoft visual studio 8/vc/atlmfc/include/afx.h(24) : fa ...
- share memory
header for public argument:shmdata.h #define TEXT_SZ 2048 struct shared_use_st { int written; char t ...