浅聊map容器

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

pair 类型(键值对)

声明:pair<T1, T2> p1;

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

make_pair(v1, v2) 以 v1 和 v2 值创建一个新 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); 创建 m2 的副本 m,m 与 m2 必须有相同的键类型和值类型

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

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

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

此外map 类额外定义了两种类型:key_typemapped_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 是一个用在 m 上的 value_type 类型的值。如果键

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

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

                                有给定键的元素

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

读取map的元素:

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

m.find(k) 如果 m 容器中存在按 k 索引的元素,则返回指向该元素的迭代器。如果不存在,则返回超出末端迭代器

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

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

从map中删除元素:

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

                   的元素个数

m.erase(p)  从 m 中删除迭代器 p 所指向的元素。p 必须指向 m 中确实存在

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

m.erase(b, e) 从 m 中删除一段范围内的元素,该范围由迭代器对 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";
    }

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值