【C++ Primer】【学习笔记】【第十章】关联容器之:multimap和multiset类型

一、基本概念
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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值