stl之关联容器学习笔记2

来源:互联网 发布:java异常处理机制叙述 编辑:程序博客网 时间:2024/05/25 01:35

set类型容器

set容器只是单纯的键的集合,其中的键必须唯一,且不能修改(const)。

举个例子:

某软件提供黑名单功能,其黑名单就可用set容器配置。在做某项操作前,先检查黑名单。

set支持大部分map的操作,有两点例外:
1、set不支持下标操作,且没有定义mapped_type。

2、set中,value_type不是pair类型,而是与key_type相同的类型。

因为只是单纯的键集合,没有关联的值。

 

添加元素操作

1、s.insert(v):在s中添加值为v的元素。返回一个pair类型,其组成包括一个指向新添加元素的迭代器,和一个是否成功添加元素的bool值。

2、s.insert(iter1,iter2):在s中添加iter1和iter2所组成的范围内的元素。如范围内存在重复的元素,则只添加一次。返回void。

 

获取元素操作

1、s.find(v):在s中搜索值为v的元素。如搜索到,则返回指向被搜索元素的迭代器。否则,返回指向超出容器末端的下一位置的迭代器。

2、s.count(v):统计s中搜索值为v的元素的个数。返回值为为元素的个数。对于set来说,返回值只有可能是0或1。

 

multimap和multiset

map和set中,一个键只能对应一个值(键唯一)。而在multimap和multiset中,允许一个键出现多次,也就形成了一键对应多值的结构。

例如,在电话号码本应用中,一个人(键)可能有多个电话号码(值)。

multimap和multiset使用之前必须包含头文件:

#include <map>

#include <set>

multimap和multiset所支持的操作,于map和set操作相同。只有一个例外:multimap不支持下标操作,这也是合理的,因为某个键可能对应多个值。

 

添加与删除元素

可直接调用insert和erase操作,基于一键对多值的结构,会有一些变化,考虑下面的例子:

multimap<string,int> si_mmap;

si_mmap.insert(make_pair(string("haha"),1));

si_mmap.insert(make_pair(string("haha"),2));

由于键不要求唯一,则每次调用insert总会添加一个元素。以上的例子,对于haha键来说,有两个值,1和2。

对应的,参数为一个键的删除操作,会删除拥有该键的所有元素,考虑以下的例子:

multimap<string,int>::size_type cnt;
cnt=si_mmap.erase("haha");

这将返回被删除元素的个数。在本例中,cnt的值为2。

当然也会有参数为一个或一对迭代器的版本,对于这个版本,只删除被指向的元素(或范围内的元素)。

 

查找元素

map和set中的元素是顺序存储的,而multimap和multiset也一样。因此,如果在容器中某个键对应多个值,则这些值是相邻着存放的。这也就意味着,在用迭代器遍历容器时,会依次返回特定键关联的所有元素。

在map和set中查找一个元素很容易,要么在,要么不在。而在multimap和multiset中,就比较复杂,因为一键可能对应多值。

为了解决这一问题。有三种可行的方案。

1、使用find和count。考虑以下的例子:

string search_item("haha");

typedef multimap<string,int>::size_type sz_type;

sz_type num=si_mmap.count(search_item);//获取容器中,键为search_item的元素的个数

multimap<string,int>::iterator iter=si_mmap.find(search_item);//获取指向第一个键为search_item的元素的迭代器

for(sz_type cnt=0;cnt!=num;++cnt,++iter)

    cout <<iter->second <<endl;

以上的例子中,关键的一点在于,如果在容器中某个键对应多个值,则这些值是相邻着存放的。

2、使用lower_bound和upper_bound函数

这是两个关联容器的操作

lower_bound参数为一个键,返回一个迭代器,指向键不小于k的第一个元素。

upper_bound参数为一个键,返回一个迭代器,指向键大于k的第一个元素。

如使用同一个键调用以上两个函数,则返回了一个迭代器范围,这个范围恰好就是指定的键对应的所有值的范围。

我们用这两个函数重写上面的例子:

typedef multimap<string,int>::iterator mm_iter;

//以下两个操作获取迭代器对

mm_iter beg=si_mmap.lower_bound(search_item);

mm_iter end=si_mmap.upper_bound(search_item);

while(beg!=end)

{

  cout <<beg->second <<endl;

  ++beg;

}

3、使用equal_range函数

这个函数使用一个键作为参数,返回一个pair类型,由lower_bound和upper_bound的返回值组成。

由以上的定义,我们可以写出更简洁的代码,重写以上的例子:

pair<mm_iter,mm_iter> pos=si_mmap.equal_range(search_item);

while(pos.first!=pos.second)

{

   cout <<pos.first->second <<endl;

   ++pos.first;

}

原创粉丝点击