常用的STL容器
STL容器很多,每一个容器就是一个类模板
一、容器种类
①顺序容器
②适配器容器
③关联容器
可参考
算法设计与分析——常用的STL容器(一)
二、关联容器
关联容器中的每个元素有一个key(关键字),通过key来存储和读取元素,这些关键字可能与元素在容器中的位置无关,所以关联容器不提供顺序容器中的 front(), push_front()、back()、push_back()以及pop_back()操作。
(1)set(集合容器)/ multiset(多重集合容器)
①set和 multiset都是集合类模板,其元素值称为关键字。set中元素的关键字是唯一的, multiset中元素的关键字可以不唯一,而且默认情况下会对元素按关键字自动进行升序排列,所以查找速度比较快,同时支持交差和并等一些集合上的运算,如果需要集合中的元素允许重复,那么可以使用 multiset
②由于set中没有相同关键字的元素,在向set中插入元素时,如果已经存在则不插入。 multiset中允许存在两个相同关键字的元素,在删除操作时删除 multiset中值等于elem的所有元素,若删除成功返回删除个数,否则返回0
③set/multiset的成员函数如下:
empty():判断容器是否为空。
size():返回容器中的实际元素个数
insert():插入元素。
erase():从容器中删除一个或几个元素。
clear():删除所有元素。
count(k):返回容器中关键字k出现的次数。
find(k):如果容器中存在关键字为k的元素,返回该元素的迭代器,否则返回end()值。
upper_bound():返回一个迭代器,指向关键字大于k的第一个元素。
lower_bound():返回一个迭代器,指向关键字不小于k的第一个元素。
begin():用于正向迭代,返回容器中第一个元素的位置。
end():用于正向迭代,返回容器中最后一个元素后面的一个位置。
rbegin():用于反向迭代,返回容器中最后一个元素的位置。
rend():用于反向迭代,返回容器中第一个元素前面的一个位置。
例如有以下程序:
#include<set>
using namespace std;
void main(){
set<int>s;
set<int>::iterator it;
s.insert(1);
s.insert(3);
s.insert(2);
s.insert(4);
s.insert(2);
printf("s: ");
for(it=s.begin();it!=s.end();it++){
printf("%d ",*it);
}
printf("\n");
multiset<int>ms;
multiset<int>::iterator mit;
ms.insert(1);
ms.insert(3);
ms.insert(2);
ms.insert(4);
ms.insert(2);
printf("ms: ");
for(it=ms.begin();mit!=ms.end();mit++){
printf("%d ",*mit);
}
printf("\n");
}
执行结果:
s:1 2 3 4
ms:1 2 2 3 4
(2)map(映射容器)/multimap(多重映射容器)
①map和 multimap都是映射类模板。映射是实现关键字与值关系的存储结构,可以使用一个关键字key来访问相应的数据值 value。set/multiset中的key和 value都是key类型,而map/multimap中的key和 value是一个pair类结构,pair类结构的声明形式如下:
struct pair{
T first;
T second;
}
也就是说,pair中由两个分量(二元组),first为第一个分量,在map中对应key,second对应value。
例如定义一个对象p1标识一个平面坐标点,并输入坐标:
pair<double,double>p1;
cin>>p1.first>>p1.second;
同时pair对==,!=,<>,<=,>=共6个运算符进行重载,提供了按照字典序对元素进行大小比较的比较运算符模板函数。
map/multimap利用pair的<运算符将所有元素(即key -value对)按key的升序排列,以红黑树的形式存储,可以根据key快速地找到与之对应的 value(查找时间为O(log2n))
map中不允许关键字重复出现,支持[]运算符;而multimap中允许关键字重复出现,但不
支持[运算符。
②map/multimap的主要成员函数如下:
empty():判断容器是否为空。
size():返回容器中的实际元素个数。
map[key]:返回关键字为key的元素的引用,如果不存在这样的关键字,则以key作为关键字插入一个元素(不适合 multimap)
insert(elem):插入一个元素elem并返回该元素的位置。
clear():删除所有元素。
find():在容器中查找元素。
count():容器中指定关键字的元素个数(map中只有1或者0)
begin():用于正向迭代,返回容器中第一个元素的位置。
end():用于正向迭代,返回容器中最后一个元素后面的一个位置。
rbegin():用于反向迭代,返回容器中最后一个元素的位置。
rend():用于反向迭代,返回容器中第一个元素前面的一个位置。
③以map为例进行说明。在map中修改元素非常简单,这是因为map容器已经对[]运算符进行了重载。例如:
map<char,int>mymap;
mymap['a']=1;
获得map中一个值的最简单方法如下:
int ans=mymap['a'];
只有当map中有这个关键字(‘a’)时才会成功,否则自动插入一个元素,其关键字为’a’,对应的值为int类型默认值0.用户可以用find()方法来发现一个关键字是否存在,传入的参数是要查找的key。
④例如有以下程序:
#include<stdio.h>
#include<map>
using namespace std;
int main(){
map<char,int>mymap;
mymap.insert(pair<char,int>('a',1));//插入方式1
mymap.insert(map<char,int>::value_type('b',2));//插入方式2
mymap['c']=3;//插入方式3
map<char,int>::iterator it;
for(it=mymap.begin();it!=mymap.end();it++)
printf("[%c,%d]",it->first,it->second);
printf("\n");
return 0;
}
执行结果:
[a,1][b,2][c,3]