STL的关键组件包括容器(container)、迭代器(iterator)及算法(algorithm),本文就这3部分内容进行总结。
容器按照类型分为序列式容器和关联式容器,其中序列式容器包括vector、deque、list等可序群集,关联式容器包括set、multiset、map、multimap等。
vector实现采用动态数组方式,可以直接存取任意元素,支持在尾部插入和删除元素且实现速度快,在数组前端和内部插入和删除元素效率较低,因为涉及到修改元素后面的所有元素位置发生改变,具体使用实例如下所示:
#include
#include
using namespace std;
int main(){
vector a;
for(int i=0;i<5;i++){
a.push_back('a'+i);
}
for(int i=0;i<5;i++){
cout< b(5,19);
b.insert(b.begin(),17);
for(int i=0;i<6;i++){
cout<
deque是double-ended queue的缩写,表示双端队列,也是采用动态数组实现,支持随机存取任何元素,可以在前端和尾部插入元素且效率高,在内部插入元素需要移动其他元素效率较低,具体使用实例如下所示:
#include
#include
using namespace std;
int main(){
deque a;
for(int i=0;i<5;i++){
a.push_back('a'+i);
a.push_front('H'+i);
}
for(int i=0;i<10;i++){
cout< b(5,19);
b.insert(b.begin()+2,17);
b.insert(b.end()-3,16);
for(int i=0;i<7;i++){
cout<
#include
#include
using namespace std;
int main(){
list a;
for(int i=0;i<5;i++){
a.push_back('a'+i);
a.push_front('H'+i);
}
for(list::iterator it=a.begin();it!=a.end();it++){
cout<<*it<<" ";
}
a.erase(a.begin(),a.end());
cout< b(5,19);
b.insert(++b.begin(),17);
b.insert(--b.end(),16);
for(list::iterator it=b.begin();it!=b.end();it++){
cout<<*b.begin()<<" ";
b.pop_front();
b.pop_back();
}
cout<
此外,string和array虽然不是容器类,但是也可以视为STL容器来使用STL算法。
关联式容器依据特定的排序准则,自动为其元素排序,排序准则以函数形式实现,比较值或者键,缺省情况下采用operator<来比较,通常采用二叉树结构存储,节点的左子树小于该元素,右子树大于该元素。关联式容器不支持push_back、push_front、pop_front、pop_back等操作,因为其是已序序列,程序员不能自己给其设定位置,插入只需使用insert,删除使用erase。set中每个元素存储一个变量,而map存储一个pair对组(2个变量),multi-前缀主要用来说明元素是可以重复的。具体的使用实例如下所示:
#include
#include
//#include
#include
迭代器分为两类:双向迭代器和随机存取迭代器,list、map、multimap、set、multiset等提供的是双向迭代器,可以双向前进即operator++、operator--,但不能随机访问即operator+、operator-。vector、deque、string等提供的是随机存取迭代器,支持随机访问。
为了处理容器内的元素,STL提供了一些标准算法,包括搜寻、排序、拷贝、重新排序、修改、数值运算等,算法并非容器的成员函数,而是一种搭配迭代器使用的全局函数,因此只需提供一份算法,可应用于所有容器类,因此降低了代码的数量,这也是泛型编程的思想即数据结构与函数分离。
#include
#include
#include
using namespace std;
int main(){
vector x;
x.push_back(2);
x.push_back(5);
x.push_back(3);
x.push_back(6);
x.push_back(1);
x.push_back(4);
vector::iterator it;
it=min_element(x.begin(),x.end());
cout<<*it<
从以上程序可以看出,min_element和max_element通过传入两个迭代器指针,获得迭代器之间的最小和最大元素的迭代器指针,使用sort对选定的两个迭代器之间的元素进行排序,find函数在指定的区间查找某个元素并返回其所在迭代器指针,reverse函数翻转指定迭代器范围内的所有元素。STL函数规定采用相同的接口表示范围,这种范围使用前闭后开区间表示,且前后顺序不能颠倒。当处理两个区间时,只需一个区间前后两端迭代器,另一个区间只需前端迭代器。
if(equal(x.begin(),x.end(),y.begin())){
cout<<"true"<
以上程序为equal、copy、resize等函数的测试实例。迭代器配接器包括安插性迭代器(Insert iterator)、流迭代器(Stream iterator)、逆向迭代器(Reverse iterator)。
首先介绍3种安插性迭代器back_inserter、front_inserter、inserter,如下图所示:
#include
#include
#include
using namespace std;
int main(){
deque x;
x.push_back(2);
x.push_back(5);
x.push_back(3);
x.push_back(6);
x.push_back(1);
x.push_back(4);
deque y;
deque::iterator it;
cout<<"x: ";
for(it=x.begin();it!=x.end();it++){
cout<<*it<<" ";
}
cout< y.resize(x.size());
copy(x.begin(),x.end(),y.begin());
cout<<"y: ";
for(it=y.begin();it!=y.end();it++){
cout<<*it<<" ";
}
cout< y.push_back(0);
cout<<"push(0) y: ";
for(it=y.begin();it!=y.end();it++){
cout<<*it<<" ";
}
cout< copy(x.begin(),x.end(),inserter(y,y.begin()+1));
cout<<"inserter: ";
for(it=y.begin();it!=y.end();it++){
cout<<*it<<" ";
}
cout< copy(x.begin(),x.end(),back_inserter(y));
cout<<"back_inserter: ";
for(it=y.begin();it!=y.end();it++){
cout<<*it<<" ";
}
cout< copy(x.begin(),x.end(),front_inserter(y));
cout<<"front_inserter: ";
for(it=y.begin();it!=y.end();it++){
cout<<*it<<" ";
}
cout<
return 0;
}
以上的测试实例可以看出,copy容器时,需resize容器的大小,否则拷贝失败,调用copy函数时,若第三个参数不直接选择目标容器的迭代器指针,也可使用安插性迭代器,使用inserter时,即调用insert函数,所以还需给出插入位置迭代器指针,使用back_inserter时,即调用push_back,同理使用front_inserter时,即调用push_front。不过要注意,map、set等关联性容器不支持push_back和push_front操作,所以只能使用inserter,vector不能使用push_front,所以。。
流迭代器包括istream_iterator和ostream_iterator两种,具体使用实例如下所示:
#include
#include
#include
#include
#include
using namespace std;
int main(){
vector coll;
copy(istream_iterator (cin),istream_iterator (),back_inserter(coll));
sort(coll.begin(),coll.end());
unique_copy(coll.begin(),coll.end(),ostream_iterator (cout,"\n"));
return 0;
}
除了安插性迭代器和流迭代器,还有一个逆向迭代器,主要是容器内预定义的rbegin和rend函数,注意rbegin和end-1相等,rend和begin-1相等。
下面介绍更易型算法,remove函数的程序实例如下:
#include
#include
#include
#include
#include
using namespace std;
int main(){
vector coll;
coll.push_back("nihao");
coll.push_back("hello");
coll.push_back("how are you");
vector::iterator end=remove(coll.begin(),coll.end(),"hello");
cout<(cout,"\n"));
cout<(cout,"\n"));
coll.erase(end,coll.end());
for(vector::iterator it=coll.begin();it!=coll.end();it++){
cout<<*it<
一天的时间,STL正式入门阶段,加油。。。