zoukankan      html  css  js  c++  java
  • STL中的map

    一、关联容器:

    按关键字有序保存元素
    map           关联数组;保存关键字-值对
    set             关键字即值,只保存关键字的容器
    multimap   关键字可以重复出现的map
    multiset     关键字可以重复出现的set

    无序关联容器
    unordered_map          用哈希函数组织的map,无序
    unordered_set            用哈希函数组织的set,无序
    unordered_multimap  哈希组织的map;关键字可以重复
    unordered_multiset    哈希组织的set,关键字可以重复

    说明:
    1、map容器:map的底层是由红黑树实现的,红黑树的每一个节点都代表着map的一个元素。该数据结构具有自动排序的功能,因此map内部的元素都是有序的,元素在容器中的顺序是通过比较键值确定的。默认使用 less<K> 对象比较。

    2、multimap容器:与map容器类似,区别只在于multimap容器可以保存键值相同的元素。

    3、unordered_map容器:该容器的底层是由哈希(又名散列)函数组织实现的。元素的顺序并不是由键值决定的,而是由键值的哈希值确定的,哈希值是由哈希函数生成的一个整数。利用哈希函数,将关键字的哈希值都放在一个桶(bucket)里面,具有相同哈希值的放到同一个桶。unordered_map内部元素的存储是无序的,也不允许有重复键值的元素,相当于java中的HashMap。

    4、unordered_multimap容器:也可以通过键值生成的哈希值来确定对象的位置,但是它允许有重复的元素。

    map和multimap容器的模板都定义在map头文件中,unordered_map和unordered_multimap容器的模板都定义在unordered_map头文件中中。

    multi前缀表明键值不必唯一,但是如果没有这个前缀,键值必须唯一。
    unordered前缀表明容器中元素的位置是通过其键值所产生的哈希值来决定的,而不是通过比较键值决定的,即容器中的元素是无序的。如果没有这个前缀,则容器中元素是由比较键值决定的,即有序。

    二、map容器

    2.1 map初始化:
    map<string, string> authors = { {"Joyce", "James"}, {"Austen", "Jane"}, {"Dickens", "Charles"} };

    2.2 插入数据
    1)insert
    map<string, int> mapStudent;//创建map
    mapStudent.insert(pair<string, int>("student_one", 22));

    或者使用make_pair
    map<string, int> mapStudent;
    mapStudent.insert(make_pair("student_one", 22));

    2)map<string, int> mapStudent;//创建map
    mapStudent.insert(map<string, int>::value_type("student_one", 22));

    3)数组方式
    map<string, int> mapStudent;//创建map
    mapStudent["student_one"] = 22;

    3)数据的访问和遍历

    map访问和查找元素的常用方法有:
    ==========================================================================================
    operator[] 访问元素,也可以用于修改某个元素的value值;不进行下标(关键字)是否存在的检查(即如果关键字不存在,程序运行不会出错),访问到某个元素时,
    如果该元素的键值不存在则直接创建该元素,返回是初始的值(比如int型的初始为0,则返回0,string初始为NULL,则返回NULL)
    at 访问元素,也可以用于修改某个元素的value值;会进行下标(关键字)是否存在的检查,如果关键字不存在,则会拋出 out_of_range 异常。
    ==========================================================================================
    利用迭代器访问元素
    ******************************************************************************************
    map<K, T>::iterator it;
    (*it).first; // the key value (of type Key)
    (*it).second; // the mapped value (of type T)
    (*it); // the "element value" (of type pair<const Key,T>)
    元素的键值和value值分别是迭代器的first和second属性。也可以用迭代器指针直接访问。
    it->first; // same as (*it).first (the key value)
    it->second; // same as (*it).second (the mapped value)

    迭代器的成员函数:
    begin    返回指向容器起始位置的迭代器(iterator)
    end    返回指向容器末尾位置的迭代器
    cbegin  返回指向容器起始位置的常迭代器(const_iterator)
    cend    返回指向容器末尾位置的常迭代器(当不需要对元素进行写访问时使用常迭代器)
    rbegin 返回指向容器起始位置的反向迭代器(reverse_iterator)
    rend 返回指向容器末尾位置的反向迭代器
    #########################################################################################
    查找某键值的元素是否存在:
    count 若存在,返回1;不存在返回0
    find 若存在返回指向元素的迭代器指针,不存在返回end()

    4) map遍历

    ① 使用前向迭代器遍历map

    map<string, int>::iterator iter;
    for (iter = mapStudent.begin(); iter != mapStudent.end(); iter++)
          cout << iter->first << " " << iter->second << endl;

    for (map<string, int>::iterator iter = mapStudent.begin(); iter != mapStudent.end(); iter++)

         cout << (*iter).first << " " << (*iter).second << endl;

    这两种形式的访问都是可以改变元素中的value值的,即可以进行写访问:

    map<string, int> mapStudent;//创建map
    mapStudent["student_one"] = 22;
    mapStudent["student_two"] = 25;
    mapStudent["student_three"] = 21;

    map<string, int>::iterator iter;
    for (iter = mapStudent.begin(); iter != mapStudent.end(); iter++)
    (*iter).second = 100; //将mapStudent中的元素value值全部改为100

    for (iter = mapStudent.begin(); iter != mapStudent.end(); iter++)

         cout << iter->first << " " << iter->second << endl; //遍历

    如果改用const_iterator,则两种方式都不能进行写访问。

    ② 使用反向迭代器遍历map

    map<string, int>::reverse_iterator iter;
    for (iter = mapStudent.rbegin(); iter != mapStudent.rend(); iter++)
        cout << iter->first << " " << iter->second << endl; //反向遍历

    ③ 使用auto关键字

    for (auto it = mapStudent.begin(); it != mapStudent.end(); it++)

          cout << it->first << " " << it->second << endl; //遍历

    ④ 使用数组的方式遍历数组

    5)数据删除

    使用erase函数

    int res = mapStudent.erase("student_one"); //删除成功返回1,失败返回0;只有使用关键字删除时才有返回值
    cout << "res=" << res << endl;

    //使用迭代器删除
    map<string, int>::iterator iter;
    iter = mapStudent.find("student_two");
    mapStudent.erase(iter);

    //使用迭代器删除一个范围的元素
    auto it = mapStudent.begin();
    mapStudent.erase(it, mapStudent.find("student_two"));

    三、multimap容器

    multimap容器保存的是有序的键/值对,但是可以保存重复的元素。multimap中会出现具有相同键值的元素序列。multimap大部分成员函数的使用方式和map相同。因为重复键的原因,multimap有一些函数的使用方式和map有一些区别。

    1、访问元素

    multimap 不支持下标运算符,因为键并不能确定一个唯一元素。和 map 相似,multimap 也不能使用 at() 函数。

  • 相关阅读:
    ASP.NET MVC Ajax下载文件(使用NPOI向现有的excel模板文件里面添加数据)
    Devexpress MVC DateEdit 设置默认的Time
    SQL 行转列(列的值不规则的数目)
    靶机Cyberry
    PHP-Audit-Labs-Day1
    DASCTF七月赛两道Web题复现
    靶机BlackMarket
    靶机CH4INRULZ_v1.0.1
    Kali中John的使用方法
    虚拟机中桥接模式和NAT模式以及仅主机模式的区别
  • 原文地址:https://www.cnblogs.com/sunshine1218/p/12081513.html
Copyright © 2011-2022 走看看