C++ 之map和unordered_map详解

简介:C++中map和unordered_map提供的是一种键值对容器,所有的数据都是成对出现的,每一对中的第一个值称之为关键字(key),每个关键字只能在map中出现一次;第二个称之为该关键字的对应值(value),一对一的映射。

区别

一.map:有序性,可应用于有顺序要求的应用中 ;unordered_map:哈希表保证了元素的查找和存储速度都非常的快
二.map:空间占用率高,红黑树的每个节点都需要保存父节点、子节点和红黑性质,增加了使用空间;
unordered_map:哈希表的建立比较耗时

map的使用

include <map>
using namespace std;
// map的构造方法1
map<char, int> map1;
map1['a'] = 88;
map1['b'] = 90;
map1['c'] = 85;

// 2
map<char, int> map2(map1.begin(), map1.end());

//3
map<char, int> map3(map2);
namedescription
begin返回指向迭代器第一个元素的迭代器
end返回指向迭代器最后一个元素的迭代器
rbegin返回逆序迭代器第一个元素的迭代器
rend返回迭代器逆序最后一个元素的迭代器
cbegin返回常量迭代器的第一个元素的迭代器
cend返回常量迭代器的最第一个元素的迭代器
crbegin返回常量迭代器逆序的第一个元素的迭代器
crend返回常量迭代器逆序的最后一个元素的迭代器
int main() {
    map<char, int>map1;
    map1['a'] = 97;
    map1['b'] = 98;
    map1['c'] = 99;

    map<char, int>::iterator it1;
    for (it1 = map1.begin(); it1 != map1.end(); ++it1) {
        cout << it1->first << "=>" << it1->second << endl;
    }

    for (auto it2 = map1.rbegin(); it2 != map1.rend(); ++it2) {
        cout << it2->first << "=>" << it2->second << endl;
    }
    return 0;
}

获取元素可以适用[]和at,如果我们索引的key并不在map对象里面,则

[]会将这个key保存到map对象中,对应的value是该类型对应的初始化值;

at会抛出异常

map1['a'] = 97;
map1['b'] = 98;
map1['c'] = 99;
cout << map1['d'] << endl;            //将map1['d']=0添加到对象中
cout << map1.at('e') << endl;      // 抛出异常

其他一些方法

find若找到该key,返回该位置的迭代器;否则返回map::end的迭代器
count包含元素计数,返回值为0或1
lower_bound返回指向所取元素的迭代器
upper_bound返回指向所取元素下一个元素的迭代器
equal_bound返回一个pair,pair的第一个内容是lower_bound的结果pair的第二个内容是upper_bound的结果
//find
map<char, int>::iterator it;
it = map.find('b');
cout << it->second << endl;                  //99
cout << map.count('a') << endl;      // 1
cout << map.count('e') << endl;      // 0

map1['a'] = 97;   map1['b'] =98;   map1['c'] = 99;   map1['d'] =100;   map1['e'] = 101;
map<char, int>::iterator itlow, itup;
itlow = map1.lower_bound('b');     // itlow points to b
itup = map1.upper_bound('d');      // itup points to e
map1.erase(itlow, itup);                    // 剩下a 和 e
map1.insert(pair<char, int>('d', 100));//a,e,d都有
 map1.erase('a');//剩下e,d
 map1.clear();//清空,但存储空间依旧存在

equal_bound

map1['a'] = 97;   map1['b'] = 98;   map1['c'] = 99;   
pair<map<char, int>::iterator, map<char, int>::iterator> ret;
ret = map1.equal_range('b');//返回一个lower_bound和一个upper_bound
cout << ret.first->first << "=>" << ret.first->second << endl;     // b=>20
cout << ret.second->first << "=>" << ret.second->second << endl;   // c=>30 

swap:

map<char, int> foo, bar;//交换两个map的内容
  foo['x'] = 100;
  foo['y'] = 200;
  bar['a'] = 10;
  bar['b'] = 20;
  bar['c'] = 30;
  foo.swap(bar);

emplace:直接在后面插入元素,不负责排序,因此速度比insert更快

map1.emplace('x',100);
map1.emplace('y',200);

unordered_map的使用方法

模板

template < class Key,                        //键值对中键的类型
           class T,                          //键值对中值的类型
           class Hash = hash<Key>,           //容器内部存储键值对所用的哈希函数
           class Pred = equal_to<Key>,       //判断各个键值对键相同的规则
           class Alloc = allocator< pair<const Key,T> >  // 指定分配器对象的类型
           > class unordered_map;

总的来说,当无序容器中存储键值对的键为自定义类型时,默认的哈希函数 hash 以及比较函数 equal_to 将不再适用,只能自己设计适用该类型的哈希函数和比较函数,并显式传递给 Hash 参数和 Pred 参数。至于如何实现自定义,后续章节会做详细讲解。

#include <unordered_map>
using namespace std;
unordered_map<string, int> strIntMap;
strIntMap map1;
strIntMap map2({ {"Tom", 80}, {"Lucy", 85} });
strIntMap map3(map2);
strIntMap map4(map3.begin(), map3.end());
unordered_map<string, string> umap2(++umap.begin(),umap.end());//通过此方式创建的 umap2 容器,其内部就包含 umap 容器中除第 1 个键值对外的所有其它键值对。

//下面实现一些方法

#include <iostream>
#include <string>
#include <unordered_map>
using namespace std;
int main()
{
    //创建空 umap 容器
    unordered_map<string, string> umap;
    //向 umap 容器添加新键值对
    umap.emplace("Python教程", "http://c.biancheng.net/python/");//向容器中添加新键值对,效率比 insert() 方法高。
    umap.emplace("Java教程", "http://c.biancheng.net/java/");
    umap.emplace("Linux教程", "http://c.biancheng.net/linux/");
    //输出 umap 存储键值对的数量
    cout << "umap size = " << umap.size() << endl;
    //使用迭代器输出 umap 容器存储的所有键值对
    for (auto iter = umap.begin(); iter != umap.end(); ++iter) {
        cout << iter->first << " " << iter->second << endl;
    }
    return 0;
}

.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值