/*
任務一:北大版 在一個非降序列中,查找與給定值相同的元素下標
寫一個 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() :
- 查找第一個大於指定值得元素,用法同上