zoukankan      html  css  js  c++  java
  • Map容器

    map容器

    是关联容器的一种,由键值对象组成,即 map 容器的元素是 pair<const K,T> 类型的对象

    map容器的类型

    1. map<K,T>容器,保存的是 pair<const K,T> 类型的元素。pair<const K,T> 封装了一对键对象,键的类型是 K,对象的类型是 T。每个键都是唯一的,所以不允许有重复的键;但可以保存重复的对象,只要它们的键不同。map 容器中的元素都是有序的,元素在容器内的顺序是通过比较键确定的。默认使用 less 对象比较。

    2. multimap<K,T> 容器和 map<K,T> 容器类似,也会对元素排序。它的键必须是可比较的,元素的顺序是通过比较键确定的。和 map<K,T> 不同的是,multimap<K,T> 允许使用重复的键。因此,一个 multimap 容器可以保存多个具有相同键值的 <const K,T> 元素。

    3. unordered_map<K,T> 中 pair< const K,T>元素的顺序并不是直接由键值确定的,而是由键值的哈希值决定的。哈希值是由一个叫作哈希的过程生成的整数,本章后面会解释这一点。unordered_map<K,T>不允许有重复的键。

    4. unordered_multimap<K,T> 也可以通过键值生成的哈希值来确定对象的位置,但它允许有重复的键。

    区别

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

    头文件

    #include<map>
    #include<unorderd_map>
    

    map的创建和初始化

    1 创建

    //map<K,T>
    map<string, size_t> people;
    

    map默认构造函数有四个参数,但常常只初始化前两个参数,用于构造pair对象,因为map容器里面的对象都是pair<string,size_t>,string 说明了键的类型,size_t说明了值的类型,可以通关first和second访问第一个值和第二个值

    2 初始化

    2.1 初始化列表,隐式的转化为pair对象

    map<string,size_t> people{{"Anni",12},{"Joe",20},{"Bob",10}};
    

    2.2 make_pair显示的构造pair对象初始化

    map<string,size_t> people{make_pair("Ann",25),make_pair("Bill", 46),make_pair("Jack", 32),make_pair("Jill", 32)};
    

    2.3 容器拷贝

    map<string,size_t> peopelCopy {people};
    //类型必须一致
    

    2.4 迭代器初始化

    map<string,size_t>peopleCopy2{people.begin(),people.end()}
    

    代码实例

    int main()
    {
        map<string,size_t> people{{"Anni",12},{"Joe",20},{"Bob",10}};
        map<string, size_t> peopleCopy{people.begin(), people.end()};
        for(auto &i:peopleCopy)
        {
            cout << i.first << " "<<i.second<<endl;
        }
        return 0;
    }
    

    3 Insert插入元素

    3.1 初始化列表插入

    由于map默认是按照less从小到大排序的,因此插入不指定插入位置。

    map<string,size_t> people{{"Anni",12},{"Joe",20},{"Bob",10}};
    people.insert({"Hon",3});
    

    3.2 make_pair构造pair对象插入

    map<string,size_t> people{{"Anni",12},{"Joe",20},{"Bob",10}};
    auto pr = make_pair("Hon",3);
    auto ret_pr = people.insert(pr);
    

    说明:

    1 make_pair返回值是一个pair对象

    2 insert的返回值仍然是一个pair对象, pair 的成员变量 first 是一个指向插入元素或阻止插入的元素的迭代器;成员变量 second 是个布尔值,如果元素插入成功,second 就为 true。

    cout<<ret_pr.first->first<<" "<<ret_pr.first->second<<endl;
    cout<<ret_pr.second<<endl;
    //Hon 3
    //True
    

    3.3 直接使用pair对象插入,右值移动

    people.insert(pair<string,size_t>{"Hon", 3});
    

    4 emplace构造元素

    4.1emplace

    emplace和insert的区别在于 emplace可以在适当的位置直接构造新元素,从而避免复制和移动操作,返回值同insert。

    map<string,size_t> people{{"Anni",12},{"Joe",20},{"Bob",10}};
    auto ret_pr = people.emplace("Kiss",9);
    

    4.2 emplace_hint

    emplace_hint() 调用使用一个迭代器作为指示符,指向先前 emplace() 调用返回的 pair 对象。如果容器使用这个提示符,那么新元素会在这个指示符表示的位置之前生成,并尽可能靠近这个位置。提示符后面的参数用来构造新元素。需要注意的是,它和 emplace() 的返回值是不一样的。emplace_hint() 的返回值不是一个 pair 对象,如果新元素被插入,它返回的是指向新元素的迭代器;如果没有插入,返回的是和这个键匹配的现有元素的迭代器,拥有相同的 key 值,如果不是现有元素的话。没有提示可以直接判断是否生成了新元素。唯一的方法是,用 size() 成员函数来获取 map 中对应元素的数量来检查 map 元素增加的数量

    auto pr = people.emplace("Kiss",9);
    auto iter = people.emplace_hint (pr.first,"Gine", 62);
    

    5 map元素访问

    5.1 迭代器

    map<string,size_t> people{{"Anni",12},{"Joe",20},{"Bob",10}};
    auto it = people.begin();
    while (it != people.end())
    {
        cout << (*it).first << " " << (*it).second << endl;
        it++;
    }
    

    5.2 at(key)

    由于at()一般会检查边界,因此要对key做异常处理

    map<string,size_t> people{{"Anni",12},{"Joe",20},{"Bob",10}};
    string key;
    try
    {
        key = "Anni";
        cout << people.at(key) << endl;
        key = "Ai";
        cout << people.at(key) << endl;
    }
    catch (const out_of_range &e)
    {
        cerr << e.what() << endl;
    }
    -------------------------------------
    12
    invalid map<K,T> key
    

    5.3 [key]

    下标运算符返回一个和 键关联的对象的引用,如果key指定的对象不存在,创建一个pair对象,值为0

    cout<<people["Anni"]<<endl;
    cout<<people["Ai"]<<endl;
    ---------------------------
    12
    0
    

    由于[key]返回的是引用,因此可以通过=修改key对应的值

    people["Ai"]=2;
    cout<<people["Ai"]<<endl;
    -----------------------
    2
    
    

    6 erase/clear 删除元素

    6.1 erase(key)

    键作为参数传递,erase 返回值是删除元素的个数,如果没有对应key返回0,否则返回1

    map<string,size_t> people{{"Anni",12},{"Joe",20},{"Bob",10}};
    string key{"Anni"};
    if(people.erase(key))
    	cout<<"erase success"<<endl;
    else
    	cout<<key<<"was not found"<<endl;
    auto it = people.begin();
    while (it != people.end())
    {
        cout << (*it).first << " " << (*it).second << endl;
        it++;
    }
    -----------------------
    erase success
    Joe 20
    Bob 10
    

    6.2 erase(iteration)

    迭代器作为参数,返回值为迭代器,返回的迭代器指向被删除元素的下一个位置(注意是排好序的),

    如果删除元素是最后一个元素,返回的迭代器指向最后一个元素。

    map<string,size_t> people{{"Anni",12},{"Joe",20},{"Bob",10}};
    auto it = people.begin();
    auto pr = people.erase(it);
    cout << (*pr).first <<" " << (*pr).second<< endl;
    -----------------------------------------
    Bob 10 //注意排序
    

    还可以删除迭代器指定范围内的元素 erase(start_iter,end_iter);

    6.3 clear()

    删除所有元素

    map<string,size_t> people{{"Anni",12},{"Joe",20},{"Bob",10}};
    cout<<people.size()<<endl;
    people.clear()
    cout<<people.size()<<endl;
    --------------------------
    3
    0
    

    Pair

    头文件:pair是包含在头文件utility中的,map头文件又包含了utility

    #inclue<utility>
    或者
    #include<map>
    

    part<T1,T2> ,T1,T2可以是任意类型

    pair<int,int> p1{10,6}
    pair<string,int> p2{"anni",5}
    pait<TreeNode,bool> p3{root,false}
    ...
    

    make_pair

    auto mypair = make_pair("hello","boy");
    auto youPair = make_pair<string,sting>("test","that");
    .....
    

    Tuple

    tuple是pair的泛化,不仅包含两个类型的对象,当要把多个对象作为一个对象传递给函数时,tuple很有用:生成一个tuple对象使用:make_tuple

    #include<tuple>
    auto my_tuple = make_tuple("name",42,"address",667,..);
    
  • 相关阅读:
    Spring Boot 属性配置和使用
    spring boot下WebSocket消息推送
    深入理解分布式事务,高并发下分布式事务的解决方案
    HashMap实现原理分析
    JVM 简述
    Java 并发之原子性与可见性
    Java 并发理论简述
    Java读取Properties文件的六种方法
    Java中的注解是如何工作的?
    XML解析——Java中XML的四种解析方式
  • 原文地址:https://www.cnblogs.com/Alexkk/p/12660511.html
Copyright © 2011-2022 走看看