/*
任务一:北大版 在一个非降序列中,查找与给定值相同的元素下标
写一个 Binarysearch在包含size个元素的、从小到大排序的int数组a里查找元素p,
如果找到,返回元素下标,如果找不到,返回-1.
*/
#include <iostream>
using namespace std;
int Binarysearch(int a[],int size,int p) {
int L=0;
int R=size-1;
while(L<=R) {//如果区间不为空就继续查找
int mid=L+(R-L)/2;//取查找区间正中元素的下标
//cout<<L<<" "<<mid<<" "<<R<<endl;
if(p==a[mid]) return mid;
else if(p>a[mid]) L=mid+1;//设置新的查找区间的左端点
else R=mid-1;//设置新的查找区间的右端点
}
return -1;
}
int main() {
int a[20]= {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
int mid;
cout<<Binarysearch(a,20,18)<<endl;//第一个参数 指向数组头的指针 第二个参数 数组大小 第三个参数 要查找的值
return 0;
}
/*
任务2:北大版 写一个函数 LowerBound,在包含size个元素的从小到大排序int数组a里查找比给定整数p小的,下标最大元素。找到则返回其下标 找不到返回-1
思考查找比给定整数p大的,下标最小元素,怎么改?
*/
#include <iostream>
using namespace std;
int LowerBound(int a[],int size,int p) {
int L=0;
int R=size-1;
int lastPos=-1;//目前为止 找到的最优解
while(L<=R) {//如果区间不为空就继续查找
int mid=L+(R-L)/2;//取查找区间正中元素的下标
//cout<<L<<" "<<mid<<" "<<R<<endl;
if(a[mid]>p) R=mid-1;//设置新的查找区间的右端点
else {
lastPos=mid;
L=mid+1;//
}
}
return lastPos;
}
int main() {
int a[20]= {0,1,2,3,4,5,6,7,8,9,10,14,15,16,17,18,29,30,41,52};
cout<<a[LowerBound(a,20,50)]<<endl;
return 0;
}
任务3: 原创版
/*
写一个函数,在包含size个元素的从小到大排序int数组a里
查找和整数p最接近的元素
*/
#include <iostream>
using namespace std;
int LowerBound(int a[],int size,int p) {
int L=0;
int R=size-1;
while(R-L>1) {//注意此处出口 最后找出L-R=1的两个值
int mid=L+(R-L)/2;//取查找区间正中元素的下标
if(a[mid]>p) R=mid;//此处不能写成mid-1
else if(a[mid]<p){
L=mid;
}else return mid;
}
cout<<L<<" "<<R<<endl;
return (p-a[L])<(a[R]-p)?L:R;
}
int main() {
int a[20]= {0,1,2,3,4,5,6,7,8,9,10,14,15,16,17,21,29,30,41,52};
cout<<a[LowerBound(a,20,18)]<<endl;
return 0;
}
改进lower
/*
写一个函数 LowerBound,在包含size个元素的从小到大排序int数组a里查找比给定整数p小的,下标最大元素。返回其下标
*/
#include <iostream>
using namespace std;
int LowerBound(int a[],int size,int p) {
int L=0;
int R=size-1;
while(R-L>1) {//注意此处出口 最后找出L-R=1的两个值
int mid=L+(R-L)/2;//取查找区间正中元素的下标
if(a[mid]>p) R=mid;//此处不能写成mid-1
else if(a[mid]<p){
L=mid;
}else return mid;
}
cout<<L<<" "<<R<<endl;
return L;
}
int main() {
int a[20]= {0,1,2,3,4,5,6,7,8,9,10,14,15,16,17,21,29,30,41,52};
cout<<a[LowerBound(a,20,18)]<<endl;
return 0;
}
改进upper呢?
任务4:algorithm里 lower 和upper 含义不一样
/*
lower_bound(r[x].begin(),r[x].end(),l)
upper_bound(r[x].begin(),r[x].end(),R)
函数lower_bound()返回第一个大于等于x的数的地址
函数upper_bound()返回第一个大于x的数的地址
*/
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int a[20]= {0,1,2,2,3,5,6,7,8,9,10,14,15,16,17,21,29,29,29,52};
cout<<*lower_bound(a,a+20,2)<<"-下标为"<<lower_bound(a,a+20,2)-a<<endl;
cout<<*upper_bound(a,a+20,2)<<"-下标为"<<upper_bound(a,a+20,2)-a<<endl;
return 0;
}
后面是转载的 QAQ https://blog.csdn.net/tiao738760029/article/details/79776445
binary_search() :
- 查找指定值,存在返回下标,否则返回假
- idx = binary_search(A,A+n,want);
lower_bound() :
- 返回一个迭代器,指向第一个 大于等于 指定值得元素
- 找不到时返回末尾迭代器,可以计算距离如果大于最大下标则不存在
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int A[14]={1,1,2,2,2,4,5,5,6,8,8,8,10,15};
int * pos;
int idx;
pos = lower_bound(A,A+14,3);//查找第一个大于等于3的元素,返回迭代器
idx = distance(A,pos);//计算连个迭代器距离,即返回目标的下标
cout<<"A["<<idx<<"]="<<*pos<<endl;
//A[5]=4;
}
upper_bound() :
- 查找第一个大于指定值得元素,用法同上