[二分法] 在一個非降序列中,查找與給定值相同的元素下標

/*

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

  • 查找第一個大於指定值得元素,用法同上
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章