算法日记(一)_m0_61723200的博客-CSDN博客

之前在这篇文章用的是自定义函数的方法进行二分查找的,今天我会用stl函数进行二分查找.

binary_search:查找某个元素是否出现,返回bool型。

lower_bound:查找第一个大于或等于某个元素的位置。

upper_bound:查找第一个大于某个元素的位置。

先看道二分查找的题 

二分搜索基础版

Description

给你一个长度为n的排列有序从小到大递增的数组, 还有q次查询, 询问一个数字在这个数组中出现的位置.

Input

第1行输入一个正整数n (1<=n<=10000001<=n<=1000000), 代表数组的长度.

第2行输入n个整数, 从小到大递增, 均在Int类型范围内, 且不重复.

第3行输入一个正整数q (1<=q<=100001<=q<=10000), 代表欲查询的次数.

第4行到第q+3行输入一个正整数, 代表欲查询的数字.

你可以认为所有输入数据均为合法输入.

Output

每行输出一个数字.

若存在这个数, 则输出对应数组位置的下标(从0开始).

若不存在这个数, 则输出-1.

Sample Input 1

5
1 3 5 7 9
3
1
7
2

Sample Output 1

0
3
-1

Hint

请不要尝试暴力查询.

首先,先看一下不用stl函数的解法

#include<iostream>
using namespace std;
int twofen(int a[],int x,int n);
int main()
{int n,x,q;scanf("%d",&n);//数组长度int a[n];for(int i=0;i<n;i++){scanf("%d",&a[i]);//输入数组元素}scanf("%d",&q);//查询次数for(int i=0;i<q;i++){scanf("%d",&x);//每次要查的数printf("%d\n",twofen(a,x,n));}
}
int twofen(int a[],int x,int n)//该题的核心函数
{int left=0,right=n-1;//左区间右区间while(left<=right)//当左边大于右边时停止搜索{int middle=(left+right)/2;//中间值if(x==a[middle])如果相等说明找到了{return middle;将中间值(它的下标)还给函数}if(x>a[middle])//如果大了{left=middle+1;//说明在右区间}else{right=middle-1;//小了,在左区间}}return -1;//没找到返回-1
}

再看看stl库函数的二分法 

#include<bits/stdc++.h>
using namespace std;
int main()
{int M,a[200005],n,x;scanf("%d",&M);//输入的数组元素个数for(int i=0;i<M;i++)scanf("%d",&a[i]);//输入数组元素scanf("%d",&n);//输入查找次数for(int j=0;j<n;j++){scanf("%d",&x);//输入每次查找的元素int t=binary_search(a,a+M,x);///该二分查找函数为bool型,判断查找的数是否存在int *k=lower_bound(a,a+M,x);///找到需要查找的数的第一个位置(为地址),即大于等于x的数int *q=upper_bound(a,a+M,x);///找到比需要查找的数大的第一个数的第一个位置(为地址)int p=q-a-(k-a);///q-a和k-a分别得出两者的数组下标if(t){if(p==1) ///数组中无重复数字x的情况printf("%d",k-a);else ///数组中有重复数字x的情况for(int w=k-a;w<q-a;w++)printf("%d ",w);//k-a就是找的那个数的地址,q-a就是第一个比找的那个数大的}else printf("-1");//puts("");cout<<endl;}return 0;
}

再看一道进阶的吧

二分搜索进阶版

Description

给你一个长度为n的排列有序从小到大递增的数组, 还有q次查询, 现在希望将一个数字插入数组之中, 但是不破坏数组原来从小到大递增的性质, 想让你写个程序帮忙找插入的位置(只寻找, 并不会插入改变原数组).

Input

第1行输入一个正整数n (1<=n<=10000001<=n<=1000000), 代表数组的长度.

第2行输入n个整数, 从小到大递增, 均在Int类型范围内, 可能会重复.

第3行输入一个正整数q (1<=q<=100001<=q<=10000), 代表欲查询的次数.

第4行到第q+3行输入一个正整数, 代表欲插入的数字.

你可以认为所有输入数据均为合法输入.

Output

每行输出一个数字.

输出对应数组位置的下标(从0开始), 即插入该数字之后该数字的数组下标.

Sample Input 1

5
4 10 70 96 100
3
3
9
111

Sample Output 1

0
1
5

还是先看不用stl库函数的方法 

#include<iostream>
using namespace std;
int n,q,x;
int main()
{cin>>n;int a[n];for(int i=0;i<n;i++){cin>>a[i];}cin>>q;for(int i=1;i<=q;i++)//这属于模板二,可以看上面附的博客{cin>>x;//要找的数int l=0,r=n;while(l<r)//相等时停止搜索{int mid=l+r>>1;//位运算除2if(a[mid]>=x)//如果大于等于要找的数r=mid;//说明在左边elsel=mid+1;//否则在右边}cout<<l<<endl;//因为二分法找的是最接近x的那个数字的位置}return 0;
}

 stl函数做法

#include<bits/stdc++.h>
using namespace std;
int main()
{int M,a[1000005]={0},n,x;scanf("%d",&M);//输入的数组元素个数for(int i=0;i<M;i++)scanf("%d",&a[i]);//输入数组元素sort(a,a+M);//排序scanf("%d",&n);//输入查找次数for(int j=0;j<n;j++){scanf("%d",&x);//输入每次查找的元素//int t=binary_search(a,a+M,x);///该二分查找函数为bool型,判断查找的数是否存在int *k=lower_bound(a,a+M,x);///找到需要查找的数的第一个位置(为地址),即大于等于x的数//int *q=upper_bound(a,a+M,x);///找到比需要查找的数大的第一个数的第一个位置(为地址)//int p=q-a-(k-a);///q-a和k-a分别得出两者的数组下标if((k-a)>=0){//if(p==1) ///数组中无重复数字x的情况printf("%d",k-a);//else ///数组中有重复数字x的情况//for(int w=k-a;w<q-a;w++)printf("%d ",w);//k-a就是找的那个数的地址,q-a就是第一个比找的那个数大的}else//如果没找就说明给出的那个x要不大于最小值,要不大于最大值,但是最小值的情况可以排除了{cout<<M;}//puts("");cout<<endl;}return 0;
}

用stl函数来实现二分查找相关推荐

  1. STL之lower_bound,upper_bound二分查找函数 结构体

    codeforces上的代码是开放的,常常就能看到本渣与大神们的差距 比如二分查找... 1.在数组中,找出第一个4所在位置 输入: 14 4 1 2 2 3 4 4 4 4 5 6 7 9 9 10 ...

  2. 【C++】C++11 STL算法(四):二分查找法(Binary search operations)、合并操作

    目录 一.lower_bound 1.原型: 2.说明: 3.官方demo 二.upper_bound 1.原型: 2.说明: 3.官方demo 三.binary_search 1.原型: 2.说明: ...

  3. 51 nod 1624 取余最长路 思路:前缀和 + STL(set)二分查找

    题目: 写这题花了我一上午时间. 下面是本人(zhangjiuding)的思考过程: 首先想到的是三行,每一行一定要走到. 大概是这样一张图 每一行长度最少为1.即第一行(i -1) >= 1, ...

  4. upperbound找不到_lower_bound()函数和upper_bound()函数,以及二分查找

    lower_bound(): 默认版本 template ForwardIterator lower_bound (ForwardIterator first, ForwardIterator las ...

  5. 考研数据结构之查找(9.8)——练习题之编写一个函数利用二分查找算法在一个有序表中插入关键字k并保持表的有序性(C表示)

    题目 编写一个函数,利用二分查找算法在一个有序表中插入一个关键字k,并保持表的有序性. 分析 先在有序表中利用二分查找算法查找关键字值等于或小于k的结点,m指向正好等于k的结点或l指向关键字正好大于k ...

  6. cuda中的二分查找

    使用背景 通常,在做高性能计算时,我们需要随机的连接某些点.这些点都具有自己的度量值,显然,度量值越大的值随机到的概率就会越大.因此,采用加权值得方法: void getdegreeSum(DG *g ...

  7. python实现二分查找_数据结构和算法:Python实现二分查找(Binary_search)

    在一个列表当中我们可以进行线性查找也可以进行二分查找,即通过不同的方法找到我们想要的数字,线性查找即按照数字从列表里一个一个从左向右查找,找到之后程序停下.而二分查找的效率往往会比线性查找更高. 一. ...

  8. c++ 二分查找的函数 lower_bound upper_bound binary_search

    简介 C++ STL 中二分查找函数主要有这三种: lower_bound() upper_bound() binary_search() 这三个函数都运用于有序区间. 用法 1. lower_bou ...

  9. STL 二分查找 upper_bound和lower_bound用法

    STL中关于二分查找的函数有三个lower_bound .upper_bound .binary_search . 这三个函数都运用于有序区间(当然这也是运用二分查找的前提),下面记录一下这两个函数. ...

最新文章

  1. Tornado 类与类组合降低耦合
  2. 写SpringBoot项目的时候,报错Ordinal parameter not bound
  3. php乱炖,linux使用crontab实现PHP执行定时任务 | 乱炖
  4. 大数据心得体会_20年备受关注的6款数据工具!谁最好用?毫无争议的答案来了...
  5. python request timeout_详解Python requests 超时和重试的方法
  6. error RC2104: undefined keyword or key name问题
  7. mysql启动日志指令_简单整理MySQL的日志操作命令
  8. SQL Server分页3种方案比拼[转]
  9. 【Unity Shader】(九) ------ 高级纹理之渲染纹理及镜子与玻璃效果的实现
  10. 双网卡,上网走外网网卡,内网走内网网卡设置。
  11. Unity 透视相机世界和屏幕坐标系转换
  12. 微信服务号 — 社区卫生服务中心申请
  13. laravel从入门到精通之 时区设置
  14. 递归解决不含连续的1的位串个数的问题
  15. 面向时空异构数据的联邦学习
  16. Failed to declare queue(s):[XXX]问题解决
  17. codeforces 427C tarjan模板题
  18. 小车红外线自主充电方案-1
  19. JavaWeb项目 学生后台管理系统 有源码!!(基于MVC设计模式)
  20. VScode下载安装+使用

热门文章

  1. Bit-Z子账号功能操作指南
  2. 优化问题中:如何得到对偶目标函数
  3. 面试题--乐视.滴滴
  4. 大二想休学,学长们有哪些建议呢
  5. 报表ReportViewer显示图片--rdlc
  6. 研究生SLAM论文阅读汇总(一)
  7. 计算机网络桂林电子科技大学试卷,计算机网络课件2-桂林电子科技大学.ppt
  8. SpringBoot的java打印票据-3
  9. 百度ai烟火识别盒子
  10. cube开源一站式云原生机器学习平台-推理服务的工程化加速