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 ∁
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 ∁
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 ∁
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: