一、基本概念
map和set容器,一个键只能对应一个实例;而multimap和multiset容器则允许一个键对应多个实例。
multimap类型使用的头文件与map类型一样,均为map;同样地,multiset类型使用的头文件与set类型一样,均为set。
二、在multimap和multiset容器中添加和删除元素
添加元素:与map和set的insert操作相同,唯一区别是可以增加具有相同键值的元素;
删除元素:与map和set的erase操作相同,区别是:带有一个键参数的erase版本将删除拥有该键的所有元素,并返回删除元素的个数;而带有一个或一对迭代器参数的版本只删除指定的元素,并返回void类型。
三、在multimap和multiset容器中查找元素
注1:在multimap和multiset容器中,所有元素键值是按照字母表顺序存放的;
注2:在multimap和multiset容器中,对于同一个键对应的多个实例,这些实例在容器中是相邻存放的。
1、使用find和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、与众不同的面向迭代器的解决方法。
注:如果k键没有关联的元素,则lower_bound和upper_bound返回相同的迭代器:都指向同一个元素或者都指向multimap/multiset的超出末端位置。
返回迭代器的关联容器操作 |
说明
|
m.lower_bound(k)
|
返回一个迭代器,指向键大于或等于k的第一个元素;
|
m.upper_bound(k)
|
返回一个迭代器,指向键大于k的第一个元素;亦即:迭代器指向该键应该插入的位置;
|
m.equal_range(k)
|
返回一个迭代器的pair对象;它的first成员等价于m.lower_bound(k),而second成员等价于m.upper_bound(k);
|
string search_item("Alain de Botton");
typedef multimap<string, string>::iterator authors_it;
authors_it beg = authors.lower_bound(search_item);
authors_it end = authors.upper_bound(search_item);
while (beg != end)
{
cout << iter->second << endl;
++beg;
}
3、方法2的升级版:equal_range函数
string search_item("Alain de Botton");
typedef multimap<string, string>::iterator authors_it;
pair<authors_it, authors_it> pos = authors.equal_range(search_item);
while (pos.first != pos.second)
{
cout << pos.first->second << endl;
++pos.first;
}
习题10.26:在multimap容器中查找并删除元素(find函数)
#include <iostream>
#include <string>
#include <map>
using namespace std;
int main()
{
// 建立multimap容器,存储作者及其作品
multimap<string, string> authors;
string author, work, searchItem;
do
{
cout << "Enter author's name(Ctrl + D or Ctrl + Z to end): " << endl;
cin >> author;
if (!cin) break;
cout << "Enter author's works(Ctrl + D or Ctrl + Z to end): " << endl;
while (cin >> work)
{
authors.insert(make_pair(author, work));
}
cin.clear();
}
while (cin);
cin.clear();
// 使用find函数在容器中查找元素,并调用erase将其删除
// 查找的元素不存在时,确保程序的正确运行
cout << "Enter the author's name that you want erase: " << endl;
cin >> searchItem;
multimap<string, string>::iterator iter = authors.find(searchItem);
if (iter != authors.end())
{
authors.erase(searchItem);
}
else
{
cout << "Can't find the author " << searchItem << "." << endl;
}
// 输出multimap对象
cout << "author\t\twork" << endl;
for (iter = authors.begin(); iter != authors.end(); ++iter)
{
cout << iter->first << "\t\t" << iter->second << endl;
}
return 0;
}
[chapter10]$ ./a.out
Enter author's name(Ctrl + D or Ctrl + Z to end):
1
Enter author's works(Ctrl + D or Ctrl + Z to end):
a b c
Enter author's name(Ctrl + D or Ctrl + Z to end):
2
Enter author's works(Ctrl + D or Ctrl + Z to end):
d e f
Enter author's name(Ctrl + D or Ctrl + Z to end):
3
Enter author's works(Ctrl + D or Ctrl + Z to end):
g h i
Enter author's name(Ctrl + D or Ctrl + Z to end):
Enter the author's name that you want erase:
2
author work
1 a
1 b
1 c
3 g
3 h
3 i
习题10.27:在multimap容器中查找并删除元素(equal_range函数)
#include <iostream>
#include <string>
#include <map>
using namespace std;
int main()
{
// 建立multimap容器,存储作者及其作品
multimap<string, string> authors;
string author, work, searchItem;
do
{
cout << "Enter author's name(Ctrl + D or Ctrl + Z to end): " << endl;
cin >> author;
if (!cin) break;
cout << "Enter author's works(Ctrl + D or Ctrl + Z to end): " << endl;
while (cin >> work)
{
authors.insert(make_pair(author, work));
}
cin.clear();
}
while (cin);
cin.clear();
// 使用euqal_range函数在容器中查找元素,并调用erase将其删除
// 查找的元素不存在时,确保程序的正确运行
cout << "V2: Enter the author's name that you want erase: " << endl;
cin >> searchItem;
typedef multimap<string, string>::iterator authors_it;
pair<authors_it, authors_it> pos = authors.equal_range(searchItem);
if (pos.first != pos.second)
{
authors.erase(pos.first, pos.second);
}
else
{
cout << "Can't find the author " << searchItem << "." << endl;
}
// 输出multimap对象
cout << "author\t\twork" << endl;
for (authors_it iter = authors.begin(); iter != authors.end(); ++iter)
{
cout << iter->first << "\t\t" << iter->second << endl;
}
return 0;
}
[chapter10]$ ./a.out
Enter author's name(Ctrl + D or Ctrl + Z to end):
1
Enter author's works(Ctrl + D or Ctrl + Z to end):
a b c
Enter author's name(Ctrl + D or Ctrl + Z to end):
2
Enter author's works(Ctrl + D or Ctrl + Z to end):
d e f
Enter author's name(Ctrl + D or Ctrl + Z to end):
3
Enter author's works(Ctrl + D or Ctrl + Z to end):
g h i
Enter author's name(Ctrl + D or Ctrl + Z to end):
V2: Enter the author's name that you want erase:
2
author work
1 a
1 b
1 c
3 g
3 h
3 i
习题10.28:在multimap容器中的元素按字典顺序输出(equal_range函数)
#include <iostream>
#include <string>
#include <map>
using namespace std;
int main()
{
// 建立multimap容器,存储作者及其作品
multimap<string, string> authors;
string author, work, searchItem;
do
{
cout << "Enter author's name(Ctrl + D or Ctrl + Z to end): " << endl;
cin >> author;
if (!cin) break;
cout << "Enter author's works(Ctrl + D or Ctrl + Z to end): " << endl;
while (cin >> work)
{
authors.insert(make_pair(author, work));
}
cin.clear();
}
while (cin);
cin.clear();
// 按姓名首字母的顺序输出作者及其作品
// Author Names Beginning with 'A':
// Author, book, book, ...
// ...
// Author Names Beginning whit 'B':
// ...
if (authors.empty())
{
cout << "Empty multimap!" << endl;
return 0;
}
string preAuthor, curAuthor;
typedef multimap<string, string>::iterator authors_it;
authors_it iter = authors.begin();
while (iter != authors.end())
{
curAuthor = iter->first;
if (preAuthor.empty() || curAuthor[0] != preAuthor[0])
{
preAuthor = curAuthor;
cout << "Author Names Beginning with '" << curAuthor[0] << "': " << endl;
}
cout << curAuthor;
pair<authors_it, authors_it> pos = authors.equal_range(curAuthor);
while (pos.first != pos.second)
{
cout << ", " << pos.first->second;
++pos.first;
}
cout << endl;
iter = pos.second;
}
return 0;
}
[chapter10]$ ./a.out
Enter author's name(Ctrl + D or Ctrl + Z to end):
B
Enter author's works(Ctrl + D or Ctrl + Z to end):
4 5 6
Enter author's name(Ctrl + D or Ctrl + Z to end):
C
Enter author's works(Ctrl + D or Ctrl + Z to end):
7 8 9
Enter author's name(Ctrl + D or Ctrl + Z to end):
A
Enter author's works(Ctrl + D or Ctrl + Z to end):
1 2 3
Enter author's name(Ctrl + D or Ctrl + Z to end):
Author Names Beginning with 'A':
A, 1, 2, 3
Author Names Beginning with 'B':
B, 4, 5, 6
Author Names Beginning with 'C':
C, 7, 8, 9