STL中部分函數的實現

1.迭代器
普通迭代器:
Container::iterator it = con.begin();
常量迭代器:只能讀不能修改 調用*元運算符重載,返回值爲const。
Container::const_iterator it ;
而const Container::iterator it ; 並非常量迭代器。
1)正向常量迭代器
Container::const_iterator it; begin() end()
2)逆向常量迭代器
Container::const_reverse_iterator it; rbegin() rend()
3)插入型迭代器(給容器中添加元素)
4)流迭代器

2.泛型算法(排序,函數對象-括號運算符重載)
容器排序:一次從容器中取出兩個數比較,那函數就是二元函數

自己實現STL庫中函數:
find_if() 尋找匹配的條件,
bind1st() 綁定第一個參數,返回一個一元函數對象
bind2nd() 綁定第二個參數,返回一個一元函數對象
not1() 取反器 接收一個一元函數對象,返回一個一元函數對象
back_insert_iterator () 插入型迭代器(類模板)
copy() 將一個容器中的內容拷貝到另一個容器中
插入型迭代器(插入器):
這裏寫圖片描述
這裏寫圖片描述
插入型迭代器常和copy配合使用。

實現代碼:

#include<iostream>
//順序容器  vector deque list
#include <vector>
#include<deque>
#include <list>
//關聯容器  set multiset map multimap
#include <set>
#include<map>
//容器適配器  stack queue prior_queue
#include<stack>
#include<queue>
#include <iterator>
#include <functional>//函數對象
#include <algorithm>//泛型算法
using namespace std;

//遍歷打印容器中的元素,通過[]運算符重載
template<typename Container>
void showContainer(const Container &con)
{
     for (int i=0;i<con.size();i++)
     {
         cout<<con[i]<<" ";
     }
     cout<<endl;
};
//遍歷打印容器中的元素,通過迭代器
template<typename Container>
void show(const Container &con1)
{
    Container::const_reverse_iterator it=con1.rbegin();
    for( ; it != con1.rend();++it)
    {
        cout<<*it<<" ";
    }
    cout<<endl;
}
//遍歷打印容器中的元素,通過迭代器
template<typename Container>
void show2(const Container &con1)
{
    Container::const_iterator it=con1.begin();
    for( ; it != con1.end();++it)
    {
        cout<<*it<<" ";
    }
    cout<<endl;
}

template<typename T>
class Cobj
{
public:
    Cobj(T value):mvalue(value){}
    bool operator()(T a)
    {
       return a > mvalue;
    }
private:
    T mvalue;
};
//my_find_if()的實現
template<typename iterator,typename Compar>//Compar類類型
iterator my_find_if(iterator first,iterator last,Compar comp)//comp是類對象(函數對象)
{
    for ( ; first!= last;++first)
    {
        if(comp(*first))//comp這個對象調用它的括號運算符重載comp.operator()
            return first;
    }
    return last;
   cout<<endl;
}
//函數調用時,Cobj的構造函數生成一個對象,在for循環中該對象調用括號運算符重載
vector<int>::iterator                      it2=my_find_if(vec.begin(),vec.end(),Cobj<int>(40));

//由於我們之前實現的my_find_if只能接收一個參數,因此若傳入兩個參數時,可將第二個參數進行綁定 ,my_bind()函數的實現 
template<typename compare ,typename T>
class _my_bind
{
public:
    _my_bind(compare &com,T val):comp(com),value(val){}
//這裏的left是二元函數對象中的第一個參數,括號運算符的重載返回類型本身就是一個bool類型
    bool operator()(T left){return comp(left,value);}
private:
      compare &comp;
      T value;

};
template<typename compare,typename T >
_my_bind<compare,T> my_bind(compare comp,T val)
{
    return _my_bind<compare,T>(comp,val);//返回一個一元函數對象
}

//簡潔版 代碼更緊湊 my_bind()的實現  類型合併,類的繼承關係
template<typename A1,typename A2,typename R>
class my_binary_function
{
public:
    typedef A1 fist_arg;
    typedef A2 second_arg;
    typedef R  return_type;
};

template<typename T>
class mygreater:public my_binary_function<T,T,bool>
{
public:
     bool operator(T a,T b)
     {
         return a > b;
     }
};

template<typename compare> //T 是compare作用域下的
class _my_bind
{
public:
    typedef typename compare::second_arg T;
    _my_bind(compare &com,T val):comp(com),value(val){}
    bool operator()(T left){return comp(left,value);}
private:
    compare &comp;
    T value;
};
template<typename compare>
_my_bind<compare> my_bind(compare comp,compare::second_arg value)
{
     return _my_bind<compare>(comp,value);
};
//這裏的綁定器bind還是使用的是my_find_if中的括號運算符重載
//實例化vector<int>::iterator it3=my_find_if(vec.begin(),vec.end(),my_bind(greater<int>(),41));

//簡潔版的my_left_bind  
template<typename A1,typename A2,typename R>//定義參數類型
class my_function
{
public:
    typedef A1 first_arg;
    typedef A2 second_arg;
    typedef R  return_type;
};

template<typename T>
class my_less:public my_function<T,T,bool>//二元函數類繼承參數類型
{
public:
    bool operator()(T a,T b)
    {
       return a < b;
    }
};

template<typename Compare>//綁定第一個參數
class _my_left_bind
{
public:
    typedef typename Compare::second_arg T;
    _my_left_bind(Compare &com,T val):comp(com),value(val){}
    bool operator()(T right)
    {
        return comp(value,right);//調用的my_less括號運算符重載
    }
private:
    Compare &comp;
    T value;
};

template<typename Compare>
_my_left_bind<Compare> my_left_bind(Compare comp,typename Compare::first_arg val)
{
    return  _my_left_bind<Compare>(comp,val);//調用的_my_left_bind括號運算符重載
}

//將一個容器中的數據放入另一個容器中,只可用於賦值,更改元素,不能添加元素,copy()函數的實現。
template<typename Inputiterator,typename Outiterator>
void my_copy(Inputiterator first,Inputiterator last,Outiterator dest)
{
    for ( ;first != last;++first)
    {
        *dest++=*first;
    }
}

// not1 not2 取反器
//not1是對一元函數取反,not2是對二元函數取反。
template<typename compare>
class _not1
{
public:
    typedef typename compare::first_arg T;//
    _not1(compare &com):comp(com){}
    bool operator()(T value){return !comp(value);}//對一元函數取反
private:
    compare comp;
    T value;
};
template<typename compare>
_not1<compare> my_not1(compare comp)
{
    return _not1<compare>(comp);
}
//函數的調用
vector<int>::iterator it4=my_find_if(vec.begin(),vec.end(),my_not1(bind1st(greater<int>(),41)));

/*
//插入型迭代器 可以給容器中添加元素,其本質就是調用的是Push_back

back_insert_iterator();
front_insert_iterator();
insert_iterator();
*/
//my_back_insert_iterator的實現
template<typename Container>
class my_back_insert_iterator//返回的是一個迭代器
{
public:
    typedef typename Container::value_type T;//value_type是庫裏面一個保存模板實例化類型的名字
    my_back_insert_iterator(Container &_con):con(_con){}
    my_back_insert_iterator& operator *(){return *this;}
    my_back_insert_iterator& operator ++(){return *this;}
    my_back_insert_iterator& operator++(int){return *this;}
    void operator=(const T &val)
    {
       con.push_back(val);  //調用容器本身的push_back()方法;
    }
private:
    Container &con;
};

template<typename Container>
my_back_insert_iterator<Container> my_back_inserter(Container &con)
{
    return my_back_insert_iterator<Container>(con);

}
int main()
{
    int array[20]={0};
    for (int i=0;i<20;++i)
    {
        array[i]=rand()%100+1;
    }

    vector<int>vec(array,array+20);

    //showContainer(vec);
    show2(vec);

    vector<int>::iterator it4=my_find_if(vec.begin(),vec.end(),my_not1(bind1st(greater<int>(),41)));
    if (it4 == vec.end())
    {
        exit(0);
    }
    vec.insert(it4,41);//insert是在迭代器之前插入一個元素
    show2(vec);



    /*list<int> mylist;
    my_back_insert_iterator<list<int>>backit(mylist);
        *backit=30;
        *backit=40;
        *back_inserter(mylist)=10;
        *back_inserter(mylist)=20;
    show2(mylist);*/


    //庫中的類模板  back_insert_iterator
    //back_insert_iterator<list<int>>backit(mylist);
    //*backit=10;
    //*backit=20;
    ////庫中的函數模板  back_inserter
    //back_inserter(mylist)=30;
    //back_inserter(mylist)=40;

    // show2(mylist);
    //sort(vec.begin(),vec.end());
    /*sort(vec.begin(),vec.end(),less<int>());
    showContainer(vec);*/

    /*sort(vec.begin(),vec.end(),greater<int>());
    showContainer(vec);*/

    //給容器中合適位置插入一個數
    /*vector<int>::iterator it2=find_if(vec.begin(),vec.end(),compare);//傳入函數指針
    if (it2 == vec.end())
    {
        exit(0);
    }
    vec.insert(it2,40);
    showContainer(vec);*/

  //自己實現一元函數
    //vector<int>::iterator it2=my_find_if(vec.begin(),vec.end(),Cobj<int>(40));//傳入對象
    //if (it2 == vec.end())
    //{
    //  exit(0);
    //}
    //vec.insert(it2,40);//insert是在迭代器之前插入一個元素
    //showContainer(vec);

    ////綁定第二個參數  自己實現的my_bind相當於庫中的bind2nd
    //vector<int>::iterator it3=my_find_if(vec.begin(),vec.end(),my_bind(greater<int>(),41));
    //showContainer(vec);
    //if (it3 == vec.end())
    //{
    //  exit(0);
    //}
    //vec.insert(it3,41);//insert是在迭代器之前插入一個元素
    //showContainer(vec);
     //綁定第一個參數  自己實現的my_bind相當於庫中的bind1st
    /*vector<int>::iterator it=my_find_if(vec.begin(),vec.end(),my_left_bind(my_less<int>(),41));
    showContainer(vec);
    if (it == vec.end())
    {
        exit(0);
    }
    vec.insert(it,41);
    showContainer(vec);*/
    //bind1st是綁定二元函數的第一個參數  bind2nd是綁定第二個參數,都是庫提供的函數
    //當從大到小排序時,即調用greater時,41應該綁定在第2個參數  a >  41找到大於41的數在之前插入
    //當從小到大排序時,即調用less時,41應該綁定在第1個參數  41 > b找到大於41的數在之前插入
    //vector<int>::iterator it4=my_find_if(vec.begin(),vec.end(),bind2nd(greater<int>(),41));
    //vector<int>::iterator it4=my_find_if(vec.begin(),vec.end(),bind1st(less<int>(),41));
    //not1是給一元函數對象取反,not2是給二元函數對象取反(真變假,假變真)
    /*vector<int>::iterator it4=my_find_if(vec.begin(),vec.end(),not1(bind2nd(less<int>(),41)));*/


    return 0;
}


//容器的遍歷
template<typename Container>
void ShowContainer2(const Container &Cont)
{
    //常量迭代器  只能讀,不能更改
    //Container::const_iterator it; //const int *p  不能更改
    //const Container::iterator it   //int *const p  能修改
    cout<<"正向迭代"<<endl;
    Container::const_iterator it1=Cont.begin();
    for ( ; it1 != Cont.end();++it1)
    {
        cout<< *it1<<" ";
    }
    cout<<endl;

    cout<<"逆向迭代"<<endl;
    Container::const_reverse_iterator rit=Cont.rbegin();
    for ( ; rit != Cont.rend();++rit)
    {
        cout<< *rit<<" ";
    }
    cout<<endl;

}

//函數調用
int main()
{
    //通用的容器四種構造方式
    vector<int> vec1;
    showContainer(vec1);

    vector<int> vec2(10); 
    showContainer(vec2);

    vector<int> vec3(10, 20);
    showContainer(vec3);

    int array[] = { 12, 4, 56, 7, 89, 4, 32, 21 };
    vector<int> vec4(array, array+8);
    showContainer(vec4);
   /* vector<int> vec1;

    cout<<vec1.size()<<endl;
    cout<<vec1.max_size()<<endl;

    for (int i=1;i<9;i++)
    {
        vec1.push_back(i*10);//尾端插入
    }

    showContainer(vec1);

    vec1.pop_back();//尾端刪除
    showContainer(vec1);

    vec1.insert(vec1.begin(),100);//首端位置處插入
    showContainer(vec1);
    if (vec1.empty())
    {
        cout<<"vec1 is empty"<<endl;
    }
    sort(vec1.begin(),vec1.end());//默認排序(從小到大)
    showContainer(vec1);

    sort(vec1.begin(),vec1.end(),greater<int>());//從大到小排序
    showContainer(vec1);

    sort(vec1.begin(),vec1.end(),less<int>());//從小到大排序
    showContainer(vec1);



    //找到第一個大於30的數刪除它  需要用迭代器來遍歷
    //第一種方法   
    vector<int>::iterator it=vec1.begin();  //每個容器有自己對應的迭代器
    for( ; it != vec1.end();++it )
    {
        if (*it > 30)
        {
            break;
        }
    }
    if (it == vec1.end())//沒找到
    {
        exit(0);
    }
    //找到了
    vec1.erase(it);
    showContainer(vec1);

    //第二種方法   實現自己的my_find  藉助函數對象Cpred


    vector<int>::iterator it2=my_findif(vec1.begin(),vec1.end(),compare);
    if (it2 == vec1.end())//沒找到
    {
        exit(0);
    }
    //找到了
    vec1.erase(it2);
    ShowContainer2(vec1);


    return 0;
}*/

庫中的sort()函數只能用於底層內存連續的數據結構進行排序
不適用於list,而適用於vector 和deque。

當出現這種情況:
這裏寫圖片描述

windowS 和 Linux:

這裏寫圖片描述

這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章