map、hash_map、unordered_map 的思考

#include <map>

map<string,int> dict;

map是基于红黑树实现的,可以快速查找一个元素是否存在,是关系型容器,能够表达两个数据之间的映射关系。

dict.insert(make_pair("abc",1));

dict.count("mn"); 看看dict中含有 mn的个数,因为元素是唯一的,所以这个返回值只有两种情况,0或者1. (multi_map就不是这样啦)

dict.find("mn");如果不存在就返回 dict.end(),如果存在就返回指向该元素的 iterator

dict["pq"]++ 相当于取出 value 来进行 ++ 再存回去,下标访问不存在的元素,将导致在map中添加一个新的元素,新的键就是该下标, value的值为默认值。

所以建立一个map的时候可以:

vector<string> L;unordered_map<string,int> dictL;
for(int i = 0; i< L.size(); i++)
   dictL[L[i]] += 1;

删除元素: dict.eraser("abc"); 返回值为删除元素的个数

dict.eraser(itr); 删除 itr 指向的元素,并且 itr 所指向元素必须是存在的,不能是 dict.end(). 这种形式的返回值为 void

遍历: for(map<string, int>::iterator itr = dict.begin(); itr != dict.end(); itr++)

cout<< itr->first <<"  " << itr->second <<endl;

map中的元素是按照健,有序的.

#include<unordered_map>

unordered_map是基于hash实现的。

unordered_map的插入、删除、查找 性能都优于 hash_map 优于 map,所以首选为 unordered_map.

它的缺陷是元素是无序的,当使用时候需要元素是有序的时候,不可以用它。

性能比较参考:http://keary.cn/?p=779

下面是它比较的代码

#include <iostream>
#include <stdlib.h>
#include <Windows.h>
#include <map>
#include <hash_map>
#include <unordered_map>
#include <algorithm>

bool MapTest()
{
    const unsigned int NUM_COUNT = 0xffffff;        // 数组长度
    const int DEFAULT_VALUE = 0;                              // 键值
    const unsigned int NUM_RANGE = 0xffffff;        // 随机数范围的最大值

    int* szNumA = new int[NUM_COUNT];
    int* szNumB = new int[NUM_COUNT];

    srand(::GetTickCount());

    for (unsigned int uiNum = 0; uiNum < NUM_COUNT; ++uiNum)
    {
        szNumA[uiNum] = (rand() * rand()) % NUM_RANGE;
        szNumB[uiNum] = szNumA[uiNum];
    }
    for (unsigned int uiNum = 0; uiNum < NUM_COUNT; ++uiNum)
    {
        std::swap(szNumB[uiNum], szNumB[(rand() * rand()) % NUM_COUNT]);
    }

    std::map<int, int> mapNum;
    std::hash_map<int, int> hMapNum;
    std::unordered_map<int, int> unMapNum;

    DWORD dwMap, dwHMap, dwUnMap;

    // 插入测试
    dwMap = ::GetTickCount();
    for (unsigned int uiNum = 0; uiNum < NUM_COUNT; ++uiNum)
    {
        mapNum.insert(std::map<int, int>::value_type(szNumA[uiNum], 0));
    }
    dwMap = ::GetTickCount() - dwMap;

    dwHMap = ::GetTickCount();
    for (unsigned int uiNum = 0; uiNum < NUM_COUNT; ++uiNum)
    {
        hMapNum.insert(std::hash_map<int, int>::value_type(szNumA[uiNum], 0));
    }
    dwHMap = ::GetTickCount() - dwHMap;

    dwUnMap = ::GetTickCount();
    for (unsigned int uiNum = 0; uiNum < NUM_COUNT; ++uiNum)
    {
        unMapNum.insert(std::unordered_map<int, int>::value_type(szNumA[uiNum], 0));
    }
    dwUnMap = ::GetTickCount() - dwUnMap;

    std::cout << "insert time of map is :" << dwMap << "ms" <<std::endl;
    std::cout << "insert time of hash_map is :" << dwHMap << "ms" <<std::endl;
    std::cout << "insert time of unordered_map is :" << dwUnMap << "ms" <<std::endl << std::endl;

    // 查找测试
    dwMap = ::GetTickCount();
    for (unsigned int uiNum = 0; uiNum < NUM_COUNT; ++uiNum)
    {
        mapNum.find(szNumB[uiNum]);
    }
    dwMap = ::GetTickCount() - dwMap;

    dwHMap = ::GetTickCount();
    for (unsigned int uiNum = 0; uiNum < NUM_COUNT; ++uiNum)
    {
        hMapNum.find(szNumB[uiNum]);
    }
    dwHMap = ::GetTickCount() - dwHMap;

    dwUnMap = ::GetTickCount();
    for (unsigned int uiNum = 0; uiNum < NUM_COUNT; ++uiNum)
    {
        unMapNum.find(szNumB[uiNum]);
    }
    dwUnMap = ::GetTickCount() - dwUnMap;

    std::cout << "search time of map is :" << dwMap << "ms" <<std::endl;
    std::cout << "search time of hash_map is :" << dwHMap << "ms" <<std::endl;
    std::cout << "search time of unordered_map is :" << dwUnMap << "ms" <<std::endl << std::endl;

    // 删除测试
    dwMap = ::GetTickCount();
    for (unsigned int uiNum = 0; uiNum < NUM_COUNT; ++uiNum)
    {
        mapNum.erase(szNumB[uiNum]);
    }
    dwMap = ::GetTickCount() - dwMap;

    dwHMap = ::GetTickCount();
    for (unsigned int uiNum = 0; uiNum < NUM_COUNT; ++uiNum)
    {
        hMapNum.erase(szNumB[uiNum]);
    }
    dwHMap = ::GetTickCount() - dwHMap;

    dwUnMap = ::GetTickCount();
    for (unsigned int uiNum = 0; uiNum < NUM_COUNT; ++uiNum)
    {
        unMapNum.erase(szNumB[uiNum]);
    }
    dwUnMap = ::GetTickCount() - dwUnMap;

    std::cout << "delete time of map is :" << dwMap << "ms" <<std::endl;
    std::cout << "delete time of hash_map is :" << dwHMap << "ms" <<std::endl;
    std::cout << "delete time of unordered_map is :" << dwUnMap << "ms" <<std::endl << std::endl;

    delete [] szNumA;
    delete [] szNumB;

    return true;
}

int main(int argc, char* argv[])
{
    MapTest();

    system("pause");
    return 0;
}

map、hash_map、unordered_map 的思考,布布扣,bubuko.com

时间: 2024-10-05 14:34:55

map、hash_map、unordered_map 的思考的相关文章

map与unordered_map

map与unordered_map的区别<此内容来源于https://www.cnblogs.com/strawqqhat/p/10602515.html> 1.需要引入的头文件不同 map:#include<map> unordered_map:#include<unordered_map> 2.内部实现机理不同 map:map内部实现了一个红黑树(红黑树是非严格平衡二叉搜索树,而AVL是严格平衡二叉搜索树),红黑树具有自动排序的功能,因此map内部的所有元素都是有序

MapReduce源码分析之Task中关于对应TaskAttempt存储Map方案的一些思考

我们知道,MapReduce有三层调度模型,即Job-->Task-->TaskAttempt,并且: 1.通常一个Job存在多个Task,这些Task总共有Map Task和Redcue Task两种大的类型(为简化描述,Map-Only作业.JobSetup Task等复杂的情况这里不做考虑): 2.每个Task可以尝试运行1-n此,而且通常很多情况下都是1次,只有当开启了推测执行原理且存在拖后腿Task,或者Task之前执行失败时,Task才执行多次. 而TaskImpl中存在一个成员变

深度理解map hash_map set

map VS hash_map 1)map存储的时候为排好序的,所以输出时候也是排序的.而hash_map不是的. 2)map具有稳定性,底层存储为树,这种算法差不多相当与list线性容器的折半查找的效率一样,都是O (log2N). hash_map使用hash表来排列配对,hash表是使用关键字来计算表位置.当这个表的大小合适,并且计算算法合适的情况下,hash表的算法复杂度为O(1)的,但是这是理想的情况下的,如果hash表的关键字计算与表位置存在冲突,那么最坏的复杂度为O(n). 3) 

map和unordered_map

1.boost::unordered_map, 它与 stl::map的区别就是,stl::map是按照operator<比较判断元素是否相同,以及比较元素的大小,然后选择合适的位置插入到树中.所以,如果对map进行遍历(中序遍历)的话,输出的结果是有序的.顺序就是按照operator< 定义的大小排序.而boost::unordered_map是计算元素的Hash值,根据Hash值判断元素是否相同.所以,对unordered_map进行遍历,结果是无序的.2.用法的区别就是,stl::map

MAP,HASH_MAP和数组时间对比

1 // ConsoleApplication5.cpp : 定义控制台应用程序的入口点. 2 // 3 4 #include "stdafx.h" 5 6 #include <iostream> 7 #include <hash_map> 8 #include <map> 9 #include <ctime> 10 11 using namespace std; 12 13 void testMap() 14 { 15 map<i

c++ map 和 unordered_map的区别

unordered_map和map类似,都是存储的key-value的值,可以通过key快速索引到value.不同的是unordered_map不会根据key的大小进行排序, 存储时是根据key的hash值判断元素是否相同,即unordered_map内部元素是无序的,而map中的元素是按照二叉搜索树存储,进行中序遍历会得到有序遍历. 所以使用时map的key需要定义operator<.而unordered_map需要定义hash_value函数并且重载operator==.但是很多系统内置的数

c++ 标准库的各种容器(vector,deque,map,set,unordered_map,unordered_set,list)的性能考虑

转自:http://blog.csdn.net/truexf/article/details/17303263 一.vector vector采用一段连续的内存来存储其元素,向vector添加元素的时候,如果容量不足,vector便会重新malloc一段更大的内存,然后把原内存中的数据memcpy到新的内存中,并free原内存块,然后将新元素加入.vector的元素插入性能跟以下几个要素关系重大: 1. 插入的位置 头部插入:将所有元素后移,然后将新元素插入 中间插入:将插入点后面的元素后移,然

【map】【unordered_map】map和unordered_map中键类型为自定义类型的操作

STL中map的底层为红黑树,所以查找的时间复杂度为O(logn). unordered_map是根据哈希值(遇到哈希值相同时用==号比较)寻找键,所以时间复杂度为O(1). 键类型为自定义类型时,map需要重载键类型的<符号,unordered_map需要定义键类型的哈希函数(在类外定义),以及重载键类型的==符号. class person1 { public: string name; int age; person1(string s,int i):name(s),age(i){} //

注释(map,unordered_map)

1.map的底层实现是红黑树,所以保证了一个稳定的动态操作时间,查询.插入.删除都是O(logN),最坏和平均都是查询效率为O(logN);unordered_map底层的实现是哈希表,查询效率为O(1),虽然是O(1),但是并不是unordered_map查询时间一定比map短,因为实际情况中还要考虑到数据量,而且unordered_map的hash函数的构造速度也没那么快,所以不能一概而论,应该具体情况具体分析.而且unordered_map是C11标准中新加的,所以编译器必须支持c11标准