• C++知识点 STL容器3—map && pair


    ~map && pair~

      map 和 pair 同样属于一种不是特别常用的的STL容器,

      但确实比 set  常用得多

      两者都是有两个关键字的STL

      且可以将 pair 类型插入 map 中

      又或者说 map 就是由一堆 pair 组成的

      且这些 pair 所表示的两个数据类型分别相同

      类似于变量和数组的关系

      map 对象是模板类,需要关键字和储存对象两个模板参数

      它可以将不同的数据类型链接起来

      比如可以把“student1”作为一个数组元素的下标来访问这个元素的值

      看起来功能很强大(大雾

      那现在让我们来康康 map 和 pair 到底怎么使用叭


       map 可以理解为一个功能更加 NB(时间和空间也更大)的二维数组(其实里面装的是一棵红黑树),而且这颗红黑树内部具有对数据自动排序的特点,常数也在可以接受的范围内

      它的功能主要是可以连接不同的数据类型

      比如字符串 -> 整形,结构体 -> 浮点数,甚至还可能有 map -> set

      听起来难以理解对吧,

      那好,让我们举个例子

      首先看一下如何定义一个 map

      先是祖传操作:STL 调用库  

    //STL容器祖传操作了
    #include <map>
    #include <string>
    #include <iostream>
    #include <cstdio>
    //可别光include<map>,map所需两种数据类型也要调用 
    using namespace std;
    map<int, string>stdname;
    int main()
    {
        
    }

       这样就声明了一个 int->string 的 map 了

      其实就是一个用 int 做引索,指向一个 string 类的指针

      祖传下一步:插入元素

      就像一张图中的一条边一样(大概是无权图吧

      map 中的元素是有联系的

      那我们这里介绍一下表示 map 中关系的一种数据类型

      就是刚才讲到的 pair(<map>中就包含了 pair 的头文件 < utility > ,所以无需再写

      pair 中只包含两个元素:first 和 second

      两个元素的数据类型可以不同

      定义 pair 的方式与 map 几乎无差:

    #include <map>
    #include <iostream>
    #include <cstdio>
    #include <string>
    using namespace std;
    int main()
    {
        pair<string,int> student1;
        student1.first = "Jxc";
        student1.second = 150;
        cout<<student1.first<<"  "<<student1.second<<endl;
        return 0;
    }

      输出结果是

    Jxc  150

      看起来很好理解叭

      你也可以将 pair 看成一个只能含有两个元素的结构体

      事实上确实如此

      而且 pair 单独拿出来用很可能比结构体还难受

      不过不要忘了我们本文真正的主角— map

      通常情况下(其实用的不算太多

      pair 一直是作为插入 map 的工具(中间商?赚常数(大雾))而存在的

      对于两个已有的对象,可以使用 make_pair 命令将两个元素合成一个 pair

    int a = 8;
    string m = "James";
    pair<int, string> newone;
    newone = makepair(a, m);

      可以对 map 使用 insert 命令来插入一个 pair,前提是 pair 的两个数据类型分别与 map 所需要的数据类型相同

       看一下如何插入一个 pair 到一个 map 中去

    map<int, string> mapStudent;  
      mapStudent.insert(pair<int, string>(1, "student_one"));  
      mapStudent.insert(pair<int, string>(2, "student_two"));  
      mapStudent.insert(pair<int, string>(3, "student_three"));  
      map<int, string>::iterator iter;  
      for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)  
        cout<<iter->first<<' '<<iter->second<<endl;  

      分析一下这段代码

      其实就是在 insert 命令中声明了 3 个不同的(但是两个元素类型分别相同的pair)

      然后将其插入名为 mapStudent 的 map 中

      建立起了三个一一映射

      这里要记住

      一个关键词只能对应一个储存对象,而一个储存对象可以由多个关键词指向

      跟其他 STL 容器一样

      祖传函数size, empty, clear, begin, end等用法都大差不差

      这里也不再过多做介绍

      STL 中祖传的迭代器也在 map 中得以实现

      和 set 一样都为双向访问迭代器

      支持读和写以及自增和自减运算

      声明方式依然是 STL 祖传的 iterator

      map<int, int> :: iterator it = mp.begin( );

      除了刚才提到的 insert 命令(这货只能插入 pair)

      erase 函数也可以用来进行插入操作

      比 insert 更强的是 erase 可以通过迭代器进行插入,也可以直接插入 pair

      用法也与其他 STL 大差不差

      最后压轴的是 find 函数

      find( x ) 可以通过 x 查找 map 中第二个类型(key)与之对应的一个二元组并返回其迭代器

      重头戏终于要来了

      map 最 nb 最吸引人的地方

      是 map 可以使用[ ]进行访问

      哦你问我[ ]这货是啥?咋用?

      哇老哥,你还没用过数组嘛

      没想到吧,map 可以像数组一样进行访问

      类似于可以用字符串当下标来访问元素

      和数组一样,map 也可以通过数组下标来进行数据修改与加和

      类似 mp[student1] = 150;这样的神奇操作

      可以实现快速的一一对应,有时还可以用来做 hash

      我们依此可以很方便地通过 key 找到 value

      特别的是

      如果没有这个 key 也就是查找不到的话

      map 中会自动新建一个 pair 储存 (key, zero)

      这里的 zero 表示的是广义的0

      可以是空字符,数字0,空串等等等等

      长此以往会占据大量空间

      所以建议使用[ ]前先 find 一下看看有没有这个二元组以避免空间冗余

      ~END~

  • 相关阅读:
    [C#.NET 拾遗补漏]:迭代器和列举器
    [C#.NET 拾遗补漏]:操作符的几个骚操作
    [C#.NET 拾遗补漏]:理解 volatile 关键字
    C#-表达式目录树
    数据源管理 | 关系型分库分表,列式库分布式计算
    Java中的经典算法之冒泡排序(Bubble Sort)
    MySQL数据库优化的八种方式(经典必看)
    mysql插入数据后返回自增ID的方法(AUTO_INCREMENT)
    MySQL 插入数据后返回自增id的方法
    查询数据库中的重复数据——MySQL数据库
  • 原文地址:https://www.cnblogs.com/Jiangxingchen/p/13416758.html
Copyright © 2020-2023  润新知