STL源码:multimap、multiset

来源:互联网 发布:南昌市网络教研平台 编辑:程序博客网 时间:2024/06/05 06:05

         multiset和multimap与set、map的特性以及用法完全相同,差别之一是它允许一个键对应多个实例,因为它们的插入操作使用的是底层RB-tree的insert_equal() 而不是insert_unique()函数。第二个差别multimap不支持下标运算,而map支持

         在电话薄中,每个人可能对应多个电话号码;作家会有多本对应的著作;这都需要用multimap来表示。

元素插入删除

        insert操作和 erase操作同样也适用于multimap以及 multiset容器。只是不同的是由于键不要求是唯一的,因此每次调用insert总会添加一个元素

    multimap<string,string> authors;    authors.insert(make_pair("Barth John","Sot-Weed Factor"));    authors.insert(make_pair("Barth John","Test"));
      

         带有一个键参数的erase版本将删除拥有该键的所有元素,并返回删除的个数。而带有一个或一对迭代器参数的版本只删除指定的元素,并返回void类型。

    multimap<string,string> authors;    authors.insert(make_pair("Barth John","Sot-Weed Factor"));    authors.insert(make_pair("Barth John","Sot-Weed Factor"));    authors.insert(make_pair("Barth John","Sot-Weed Factor"));    string searchStr("Barth John");    multimap<string,string>::size_type cnt = authors.erase(searchStr);    cout << cnt << endl;//cnt == 3

查找元素

        关联容器nap和set的元素是按照顺序存储的,而multimap和multiset也一样。因此,在multiset和multim容器中,如果某个键对应于多个实例,则这些实例在容器中必然相邻存放。  因此,在遍历multimap/multiset容器时,可以保证依次返回特定键所关联的所有元素

1、使用find和count

 使用count函数可以求出某个键出现的次数,而find操作将返回一个迭代器,指向第一个拥有正在查找的键的实例。

string search_item("Alain de Botton");  typedef multimap<string,string>::size_type sz_type;  sz_type entries = authors.count(search_item);    multimap<string,string>::iterator iter = authors.find(search_item);  for (sz_type cnt = 0;cnt != entries; ++cnt,++iter)  {      cout << iter -> second << endl;  }  

2、面向迭代器的解决方案

 下表列出的这些操作适用于所有的关联容器,也可用于普通的map和set容器,但是更常用于multiamp和multiset容器。所有的这些操作都需要一个键,并返回一个迭代器。

返回迭代器的关联容器操作

m.lower_bound(k)

返回一个迭代器,指向键不小于k的第一个元素

m.upper_bound(k)

返回一个迭代器,指向键大于k的第一个元素

m.equal_range(k)

他的first成员等价于m.lower_bound(k),

second成员等价于m.upper_bound(k)

参考这里的

       在同一个键上调用lower_bound函数和upper_bound函数将产生一个迭代器范围,指出该键所关联的所有元素。如果该键在容器中存在,则会获得两个不同的迭代器:lower_bound返回的迭代器指向该键关联的第一个实例,而upper_bound返回的迭代器则指向最后一个实例的下一位置。如果该键不在multimap中,这两个操作将返回同一个迭代器,都指向同一个元素或者同时指向multimap超出末端的位置。

    typedef multimap<string,string>::iterator authors_it;    string searchVal = "Barth John";    authors_it beg = authors.lower_bound(searchVal),               end = authors.upper_bound(searchVal);    while (beg != end)    {        cout << beg -> second << endl;        ++ beg;    }

3、equal_range函数

         可用通过调用equal_range函数来取代调用upper_bound和lower_bound函数。equal_range函数返回存储一对迭代器的pair对象。如果该值存在,则pair对象中的第一个迭代器指向该键关联的第一个实例,第二个迭代器指向该键关联的最后一个实例的下一位置。如果找不到匹配的元素,则pair对象中的两个迭代器都将指向此键应该插入的位置。

    pair<authors_it,authors_it> pos        = authors.equal_range(searchVal);    while (pos.first != pos.second)    {        cout << pos.first -> second << endl;        ++ pos.first;    }


0 0
原创粉丝点击