一、pair简介
在介绍这几种容器之前,我们先来看下pair,pair是一种模板类型,其中包含了两个数据值,两个数据的类型可以不同,定义如下:
pair<int, string> a;
表示a中有两个数据类型,一个是int类型,一个是string类型的,如果在创建pair时候没有对其初始化,则调用默认的构造函数对其初始化。
也可以按照以下的方式在定义的时候进行初始化
pair<int, string> a(3, "boy");
生成一个pair对象
我们可以使用make_pair对已存在的两个数据构造一个新的pair类型,如下所示:
int Int_Data = 3;
string String_Data = "boy";
pair<int, string> Pair;
Pair = make_pair(Int_Data, String_Data);
那么make_pair是如何创建的呢。
下面我们来看下C++98中make_pair是如何创建的
template <class T1,class T2>
pair<T1,T2> make_pair (T1 x, T2 y)
{
return ( pair<T1,T2>(x,y) );
}
由此可见make_pair内部调用了拷贝构造函数,直接返回一个pair对象。
pair结构
由此可见pair的两个成员分别是first与second。
当我们需要访问pair里面的成员时,便用点操作符来访问它的成员。
二、set(集合)
(1)set特性
- set的元素的键值就是实值,实值就是键值,仅有一个值。
- 不允许有两个元素拥有相同的键值。
- 所有的元素键值都会被自动排序(默认情况下是升序)
- set的iterators是一种constant itertors(相对于mutable iterators)。
- 是使用红黑树作为底层的数据结构
template < class T, // set::key_type/value_type
class Compare = less<T>, // set::key_compare/value_compare
class Alloc = allocator<T> // set::allocator_type
> class set;
set也是一个模板,它的第一个模板参数是键值类型。第二个参数是一个仿函数,它传入了键值的比较方式(默认升序),第三个参数是空间配置器。
(2)set成员类型
在C++98与C++11中set的成员类型并没有改变多少,下面我们来看下在C++98下的成员类型:
(3)set常用接口
接下来我们看下Set的常用接口。
(4)set的使用
测试程序代码如下:
#include <iostream>
#include <set>
using namespace std;
int main()
{
int arr[] = { 0,5,6,7,1,2,3,4 };//默认排序
set<int> _Set(arr, arr + sizeof(arr) / sizeof(arr[0]));
cout << "Size=" << _Set.size() << endl;
cout << "5 Count=" << _Set.count(5) << endl;
_Set.insert(5);
cout << "Size=" << _Set.size() << endl;
cout << "5 Count=" << _Set.count(5) << endl;
_Set.insert(9);
cout << "Size=" << _Set.size() << endl;
cout << "9 Count=" << _Set.count(9) << endl;
_Set.erase(3);
cout << "Size=" << _Set.size() << endl;
cout << "3 Count=" << _Set.count(3) << endl;
_Set.erase(10);
cout << "Size=" << _Set.size() << endl;
cout << "10 Count=" << _Set.count(10) << endl;
set<int>::iterator iter1 = _Set.begin();
set<int>::iterator iter2 = _Set.end();
for (; iter1 != iter2; iter1++)
cout << *iter1 << " ";
cout << endl;
//此处使用STL的算法find并不是一个好的方法
iter1 = find(_Set.begin(), _Set.end(), 7);
if (iter1 != _Set.end())
cout << *iter1 << endl;
else
cout << "not find!" << endl;
iter1 = find(_Set.begin(), _Set.end(), 12);
if (iter1 != _Set.end())
cout << *iter1 << endl;
else
cout << "not find!" << endl;
//根据容器所提供的find函数来搜索元素
//会比STL中算法find更有效。因为stl中find只是循序搜索
iter1 = _Set.find(0);
if (iter1 != _Set.end())
cout << *iter1 << endl;
else
cout << "not find!" << endl;
iter1 = _Set.find(15);
if (iter1 != _Set.end())
cout << *iter1 << endl;
else
cout << "not find!" << endl;
system("pause");
return 0;
}
运行结果如下:
三、map(映射)
(1)map特性
- 所有的元素都会根据元素的键值自动被排序(默认升序)。
- map的所有元素都是pair,同时拥有键值key与实值value。
- map不允许两个元素拥有相同的键值。
- map的键值是不能被修改的,但是实值可以被修改。
- map底层使用的数据结构是红黑树。
- map重载了[],查询速度快。
template < class Key, // map::key_type
class T, // map::mapped_type
class Compare = less<Key>, // map::key_compare
class Alloc = allocator<pair<const Key,T> > // map::allocator_type
> class map;
map也是一个模板,它有四个模板参数类型,第一个是键值的类型,第二个是实值类型,第三个是仿函数,传入的是键值比较方式,默认升序,第四个参数是空间配置器。
(2)map成员类型
(3)map常用接口
注意:
map在次多了一个operator[]
mapped_type& operator[](const key_type& k)
map中的operator[ ]是最常用的,然而在set中并没有对它进行重载。作用是:如果map中有k,则它就把这个k所对应的value的引用返回,如果map中没有这个k,这时它会调用insert(pair<K,V>(k,V()))
,将k和V的缺省值对应插入进去,并返回这个value的引用。
(4)map的使用
测试程序代码如下:
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main()
{
//由于string是键值,int是实值
//所以出来的顺序不一定是1234
map<string, int> _Map;
_Map[string("张三")] = 1;
_Map[string("李四")] = 2;
_Map[string("王五")] = 3;
pair<string, int> _Pair(string("小六"), 4);
_Map.insert(_Pair);
map<string, int>::iterator iter = _Map.begin();
for (; iter != _Map.end(); ++iter)
{
cout << iter->first << " " << iter->second << " ";
}
cout << endl;
map<string, int>::iterator iter2;
iter2 = _Map.find(string("小六"));
if (iter != _Map.end())
cout << "find" << endl;
else
cout << "not find" << endl;
iter2->second = 5;
cout << iter2->first << " " << iter2->second << endl;
cout << _Map.empty() << endl;
_Map.clear();
cout << _Map.empty() << endl;
return 0;
}
运行结果如图:
四、multiset
multiset的特性和用法与set完全相同,唯一的差别在于它允许键值重复,它的插入操作采用的底层机制是红黑树的insert_equal()而不是insert_unique()。
1. multiset的删除是删除所有值为key的结点。
2. multiset允许键值重复,调用的是insert_equal()。
五、multimap
multimap的特性和用法与map完全相同,唯一的差别在于它允许键值重复,它的插入操作采用的底层机制是红黑树的insert_equal()而不是insert_unique()。
multimap中并没有向map一样的有operator[ ],因为编译器也并不知道这样会返回多少个结果。
1. multimap的键值key和元素value是多对多的关系。
2. 允许键值重复。
3. 删除key既是删除所有值为key的元素。
4. 没有向map一样的有operator[ ]。