在进入map容器前先看看map容器内存放的值的类型:pair

pair 类型(键值对)

声明:pair<T1, T2> p1;

声明并初始化:pair<T1, T2> p1(v1, v2);

make_pair(v1, v2)

也可以这么使用:auto pair = make_pair(v1, v2);

OK,简单的聊完了pair类型,接下来我们就进入map容器

Map容器:

map 是键-值对的集合。map 类型通常可理解为关联数组

map的声明:

map<k, v> m; 创建一个名为 m 的空 map 对象,其键和值的类型分别为 k 和 v

map<k, v> m(m2);

map<k, v> m(b, e); 创建 map 类型的对象 m,存储迭代器 b 和 e 标记的范围内所有

                                元素的副本。元素的类型必须能转换为 pair<const k, v>

注意这里的k是const类型,意味着在使用的过程中k值是不能修改的。

此外map 类额外定义了两种类型:key_type 和 mapped_type,以获得键或值的

类型。在学习 map 的接口时,需谨记 value_type 是 pair 类型,它

的值成员可以修改,但键成员不能修改。

OK,那么简单的了解 了map后,我们来看看如何使用map,

首先如何给map添加元素:

1.使用下标:

map <string, int> word_count;

word_count["Anna"] = 1;

这段代码的解释如下:

首先会在word_count中查找键为Anna的元素,但是没有找到。于是将一个新的键值对插入其中,注意此时他的值是采用初始化,在本例中为0;然后紧接着将值插入其中,并将它赋值为1.注意这里和使用下标访问vector容器不同,若map中无此元素,会在map中插入该元素,但是vector不会。这里需要注意下黄色的这句话,这个就是map容器和vector容器在下标查询这块的区别。

那么如果我想在map容器中查询一个键值是否存在,但是有不想去插入那怎么办呢?别急,我们后面会详细说道的。

2.map 容器提供的 insert 操作

m.insert(e)                 在m中插入键值对e。如果m中原来就有e,则insert不作为

                                  该函数返回一个 pair 类型对象,包含指向键为 e.first 的元素的 ma迭代

                                  器,以及一个 bool 类型的对象,表示是否插入了该元素 

m.insert(beg, end)        beg 和 end 是标记元素范围的迭代器,其中的元素必须为

                                      m.value_type 类型的键-值对。对于该范围内的所有元素,

                                      如果它的键在 m 中不存在,则将该键及其关联的值插入到 m。

                                      返回 void 类型

m.insert(iter, e)

                               (e.first)不在 m 中,则创建新元素,并以迭代器 iter 为

                                起点搜索新元素存储的位置。返回一个迭代器,指向 m 中具

                                有给定键的元素

添加完元素我们结下来看看如何取元素:

读取map的元素:

m.count(k) 返回 m 中 k 的出现次数

m.find(k)

对于 map 对象,count 成员的返回值只能是 0 或 1。所以count可以检查map对象中某键是否存在

注意这里的count用法,我们刚刚说过的如果我仅仅只是想查找键,并不想插入该键,我们就可以使用count(k)来解决这个问题

从map中删除元素:

m.erase(k)  删除 m 中键为 k 的元素。返回 size_type 类型的值,表示删除

                   的元素个数

m.erase(p)

                    的元素,而且不能等于 m.end()。返回 void

m.erase(b, e)

                        b 和 e 必须标记 m 中的一段有效范围:即 b 和 e 都必须指向 m

                        中的元素或最后一个元素的下一个位置。而且,b 和 e 要么相等

                        (此时删除的范围为空),要么 b 所指向的元素必须出现在 e 所

                        指向的元素之前。返回 void 类型

注意:map 容器的 erase 操作返回 void,而顺序容器的 erase 操作则返回一个迭代器,指向被删除元素后面的元素。

了解完了map容器的基本使用,我们可以做几道题来练习练习:

1.使用map完成编写一个记录单词个数的代码

2.定义一个 map 对象,其元素的键是家庭姓氏,而值则是
     存储该家庭孩子名字的 vector 对象。为这个 map 容器
    输入至少六个条目。通过基于家庭姓氏的查询检测你的
    程序,查询应输出该家庭所有孩子的名字。

3.把上一题的 map 对象再扩展一下,使其 vector 对象存
    10.19: 储 pair 类型的对象,记录每个孩子的名字和生日。相
    应地修改程序,测试修改后测试程序以检查所编写的 
    map 是否正确。

---------------------------------------------------------------------------------------------------------------------------------相关代码如下:

1.

map<string, int> word_num;
     string word;
 for (int i = 0; i < 5; i++)
     {
         cin >> word;        word_num[word]++;
     }

2.

map<string,vector<string>>Genealogy;
     string surname; 
     string name;
     vector<string> fullname;
     cout << "请输入一个姓和该家庭的所有的孩子\n";
     cout << "请输入一个姓\n";
     cin >> surname;
     cout << "请输入该家庭的所有的孩子\n";
     for (int i = 0; i < 6; i++)
     {
         cin >> name;
         fullname.push_back(name);
     }
     Genealogy.insert(make_pair(surname,fullname));
     cout << "请输入需要查询的姓氏\n";
     cin >> surname;
     auto it = Genealogy.find(surname);
     if ( Genealogy.end() != it)
     {
         
         auto it1 = fullname.begin();
         if (fullname.end() != it1)
         {
             cout << "该姓氏家庭的孩子如下:\n";
             while (fullname.end() != it1)
             {
                 cout << *it1 << endl;
                 it1++;
             }
         }
         else
         {
             cout << "该姓氏家庭绝后了\n";
         }
     }

3.

map<string,vector<pair<string, string>>>Genealogy;
     string surname; 
     string name;
     string birthday;
     vector<pair<string,string>> fullname;
     cout << "请输入一个姓和该家庭的所有的孩子\n";
     cout << "请输入一个姓\n";
     cin >> surname;
     cout << "请输入该家庭的所有的孩子名字和生日\n";
     for (int i = 0; i < 6; i++)
     {
         cin >> name>>birthday;
         fullname.push_back(make_pair(name,birthday));
         
     }
     Genealogy.insert(make_pair(surname,fullname));
     cout << "请输入需要查询的姓氏\n";
     cin >> surname;
     auto it = Genealogy.find(surname);
     if ( Genealogy.end() != it)
     {
         
         auto it1 = fullname.begin();
         if (fullname.end() != it1)
         {
             cout << "该姓氏家庭的孩子如下:\n";
             while (fullname.end() != it1)
             {
                 cout <<"姓名"<<it1->first<<"生日"<<it1->second<< endl;
                 it1++;
             }
         }
         else
         {
             cout << "该姓氏家庭绝后了\n";
         }
     }
     else
     {
         cout << "您要查找的姓氏不存在\n";
     }