自己实现STL模板upper_bound() 和lower_bound()

本文介绍了如何自己实现STL中的upper_bound()和lower_bound()函数,详细阐述了这两个函数的用法和作用。upper_bound()在非递减序列中找到大于val的最小元素的迭代器位置,而lower_bound()则找到大于等于val的最小元素的迭代器位置。同时指出,在set中可以直接使用s.upper_bound(val)和s.lower_bound(val)。另外,文章提到binary_search()函数在set中并不适用,它用于检查非递减序列中是否存在特定值。

一、upper_bound() 

用法upper_bound(iterator,iterator,val)  在set中,还可以s.upper_bound(val);

作用 在一个左闭右开非递减序列中,找一个大于val的最小的数的地址,如果序列中都大于val,返回左区间,都不大于val,返回右区间。

**在一个递增序列[L,R)中,二分查找大于val最小的数*/
template<class F,class T>
F upper_boundSQ(F s,F e,T val)
{
    //if(*s>val)return s;
    F L=s,R=e-1;
    //if(*R<=val)return e;
    while(L<=R)
    {
        F mid=L+(R-L)/2;
        if(L==R&&*mid>val)return mid;
        else if(*mid<=val)
            L=mid+1;
        else
            R=mid-1;
    }
    return L;
}
int main ()
{
    vector<int> a;
    a.push_back(1);
    a.push_back(1);
    a.push_back(2);
    a.push_back(3);
    a.push_back(4);
    a.push_back(5);
    //a.size()=6
    /**upper_bound(iterator,iterator,val)一个左闭右开递增序列,找一个大于val的最小的数的地址
    如果序列中都大于val,返回左区间,都不大于val,返回右区间*/
    cout<<upper_bound(a.begin(),a.end(),0)-a.begin()<<endl;//输出0 (a.begin())
    cout<<upper_bound(a.begin(),a.end(),1)-a.begin()<<endl;//输出2 (a[2])
    cout<<upper_bound(a.begin(),a.end(),6)-a.begin()<<endl;//输出6 (a.end())
    ///////
    cout<<"myself"<<endl;
    cout<<upper_boundSQ(a.begin(),a.end(),0)-a.begin()<<endl;//输出0 (a.begin())
    cout<<upper_boundSQ(a.begin(),a.end(),1)-a.begin()<<endl;//输出2 (a[2])
    cout<<upper_boundSQ(a.begin(),a.end(),6)-a.begin()<<endl;//输出6 (a.end())
    return 0;
}
二、lower_bound() 

用法lower_bound(iterator,iterator,val)  在set中,还可以s.lower_bound(val);

作用: 在一个左闭右开非递减序列中,找一个大于等于val的最小的数的地址,如果序列中都大于等于val,返回左区间,都小于val,返回右区间。

#include <iostream>
#include <vector>
#include <cstdio>
#include <algorithm>
#include <map>
#include <set>
using namespace std;
#define rep(i,n) for(int i=0;i<n;i++)
#define pb push_back
#define M 100005
#define CLS(x,v) memset(x,v,sizeof(x))
#define pii pair<int,int>
#define LL long long

/**在一个递增序列[L,R)中,二分查找大于val最小的数*/
template<class F,class T>
F lower_boundSQ(F s,F e,T val)
{
    //if(*s>=val)return s;
    F L=s,R=e-1;
    //if(*R<val)return e;
    while(L<=R)
    {
        F mid=L+(R-L)/2;
        if(L==R&&*mid>val)return mid;
        else if(*mid<val)
            L=mid+1;
        else
            R=mid-1;
    }
    return L;
}
int main ()
{
    vector<int> a;
    a.push_back(1);
    a.push_back(1);
    a.push_back(2);
    a.push_back(4);
    a.push_back(5);
    a.push_back(6);
    //a.size()=6
    /**lower_bound(iterator,iterator,val)一个左闭右开递增序列,找一个>=val的最小的数的地址
    如果序列中都>=val,返回左区间,都<val,返回右区间*/
    cout<<lower_bound(a.begin(),a.end(),0)-a.begin()<<endl;//输出0 (a.begin())
    cout<<lower_bound(a.begin(),a.end(),1)-a.begin()<<endl;//输出0 (a[0])
    cout<<lower_bound(a.begin(),a.end(),2)-a.begin()<<endl;//输出2 (a[2])
    cout<<lower_bound(a.begin(),a.end(),3)-a.begin()<<endl;//输出3 (a[3]=4)
    cout<<lower_bound(a.begin(),a.end(),6)-a.begin()<<endl;//输出5 (a[5]=6)
    cout<<lower_bound(a.begin(),a.end(),100)-a.begin()<<endl;//输出6 (a.end())
    ///////
    cout<<"myself"<<endl;
    cout<<lower_boundSQ(a.begin(),a.end(),0)-a.begin()<<endl;//输出0 (a.begin())
    cout<<lower_boundSQ(a.begin(),a.end(),1)-a.begin()<<endl;//输出0 (a[0])
    cout<<lower_boundSQ(a.begin(),a.end(),2)-a.begin()<<endl;//输出2 (a[2])
    cout<<lower_boundSQ(a.begin(),a.end(),3)-a.begin()<<endl;//输出3 (a[3]=4)
    cout<<lower_boundSQ(a.begin(),a.end(),6)-a.begin()<<endl;//输出5 (a[5]=6)
    cout<<lower_boundSQ(a.begin(),a.end(),100)-a.begin()<<endl;//输出6 (a.end())
    return 0;
}
三、binary_search()

用法bool  binary_search(iterator,iterator,val)  在set中,没有这个方法!

作用: 在一个左闭右开非递减序列中,查找是否存在等于val的数。

/**在一个递增序列[L,R)中,二分查找是否存在==val的数*/
template<class F,class T>
bool binary_searchSQ(F s,F e,T val)
{
    F L=s,R=e-1;
    while(L<=R)
    {
        F mid=L+(R-L)/2;
        if(*mid==val)return 1;
        else if(*mid<val)
            L=mid+1;
        else
            R=mid-1;
    }
    return 0;
}
int main ()
{
    vector<int> a;
    a.push_back(1);
    a.push_back(1);
    a.push_back(2);
    a.push_back(4);
    a.push_back(5);
    a.push_back(6);
    //a.size()=6
    /**binary_search(iterator,iterator,val)一个左闭右开递增序列,查找是否存在一个==val*/
    cout<<binary_search(a.begin(),a.end(),0)<<endl;//输出0
    cout<<binary_search(a.begin(),a.end(),1)<<endl;//输出1
    cout<<binary_search(a.begin(),a.end(),2)<<endl;//输出1
    cout<<binary_search(a.begin(),a.end(),3)<<endl;//输出0
    cout<<binary_search(a.begin(),a.end(),6)<<endl;//输出1
    cout<<binary_search(a.begin(),a.end(),100)<<endl;//输出0
    ///////
    cout<<"myself"<<endl;
    cout<<binary_searchSQ(a.begin(),a.end(),0)<<endl;//输出0
    cout<<binary_searchSQ(a.begin(),a.end(),1)<<endl;//输出1
    cout<<binary_searchSQ(a.begin(),a.end(),2)<<endl;//输出1
    cout<<binary_searchSQ(a.begin(),a.end(),3)<<endl;//输出0
    cout<<binary_searchSQ(a.begin(),a.end(),6)<<endl;//输出1
    cout<<binary_searchSQ(a.begin(),a.end(),100)<<endl;//输出0
    return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值