您的位置:首页 > 编程语言 > C语言/C++

算法:C++实现二分查找

2017-08-20 09:25 501 查看
事出有因,昨晚内推笔试题,采用遍历的方式提示耗时,由于系统原因(忍不住再次吐槽一下考试系统,估计是单线程队列模式),本地测试通过但是系统提交不上去,好不容易提交上去发现没通过全部的测试用例,当考虑用二分查找方式实现时时间已耗完。

题目:新兵入队,编号从1开始依次递增(10个人的话编号是1-10),共分成N个队伍,指定每个队伍中的人数并分配新兵(按照编号顺序),然后随机选取Q个测试qi(i=1-Q),指出编号为qi的新兵在哪一组。举例:新兵分为五组N=5,从第一组到第五组的人数分别为2,7,3,4,9。测试三个数据Q=3,编号为1的在第一组,编号为25的新兵在第五组,编号为11的新兵在第3组。

测试用例:

输入

5

2 7 3 4 9

3

1 25 11


输出:

1

5

3


思路:开始最先想到的是先记录每个组的编号的大小区间(例如测试用的第二组区间为3-9),然后根据每个编号,遍历每个组数判断是否在该组的区间内,如果在就输出,不在继续往后找。这种暴力的方式在本地编译没有问题,但是考试系统就出现了问题。由于编号是有序的,且按照有序的方式进行分组,满足二分查找的前提,我们可以记录当前组的最大编号形成一个序列(上述五个组分别为2 9 12 16 25),然后查找大于测试qi的最小数所在的组就解决了问题。重点是本来想自己实现二分查找,发现STL中已经集成了相关类型的函数模板lower_bound(),先实现一下:

#include<iostream>
#include<vector>
#include<algorithm>
int main(){
long long num;
std::cin>>num;
long long count=0;
std::vector<int> groups(num);
for(long long i=0;i<num;++i){
long long temp;
std::cin>>temp;
groups[i]=count+temp;
count+=temp;
}
long long q;
std::cin>>q;
long long qi;
for(long long i=0;i<q;++i){
std::cin>>qi;
long long mid=std::lower_bound(groups.begin(),groups.end(),qi)-groups.begin();
std::cout<<mid+1<<std::endl;

}
return 0;
}


附上常见的二分查找(递归和非递归):

递归:
int find(vector<int>const &vec,int start,int end,int value){
if(start>end){
return -1;
}
int mid=(start+end)>>1;
if(vec[mid]==value){
return mid;
}
if(vec[mid]<value){
return find(vec,mid+1,end,value);
}
if(vec[mid]>value){
return find(vec,start,mid-1,value);
}
}
非递归
int find(vector<int>const &vec,int start,int end,int value){
while(start<=end){
int mid=(start+end)>>1;
if(vec[mid]==value){
break;
}
if(vec[mid]<value){
start=mid+1;
}
else{
end=mid-1;
}
}
return -1;
}


有关STL二分查找的算法,可以参见另一篇博客STL二分查找算法
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  二分查找 C++