zoukankan      html  css  js  c++  java
  • (转载)STL map与Boost unordered_map的比较

    原链接:传送门

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

    用法的区别就是,stl::map 的key需要定义operator< ; 而boost::unordered_map需要定义hash_value函数并且重载operator==。对于内置类型,如string,这些都不用操心。对于自定义的类型做key,就需要自己重载operator< 或者hash_value()了。 

    最后,当不需要结果排好序时,最好用unordered_map。原因在于

    • 运行效率方面:unordered_map最高,而map效率较低但 提供了稳定效率和有序的序列。
    • 占用内存方面:map内存占用略低,unordered_map内存占用略高,而且是线性成比例的。

    其实,stl::map对于与Java中的TreeMap,而boost::unordered_map对应于java中的HashMap。 

     

    stl::map

    #include<bits/stdc++.h>
    using namespace std;
    
    struct person
    {
        string name;
        int age;
    
        person(string name, int age)
        {
            this->name =  name;
            this->age = age;
        }
    
        bool operator < (const person &p) const
        {
            return this->age < p.age;
        }
    };
    map<person, int> m;
    
    int main()
    {
        person p1("Tom1", 20);
        person p2("Tom2", 22);
        person p3("Tom3", 22);
        person p4("Tom4", 23);
        person p5("Tom5", 24);
        m.insert(make_pair(p3, 100));
        m.insert(make_pair(p4, 100));
        m.insert(make_pair(p5, 100));
        m.insert(make_pair(p1, 100));
        m.insert(make_pair(p2, 100));
    
        for(map<person, int>::iterator iter = m.begin(); iter != m.end(); iter++)
        {
            cout << iter->first.name << "	" << iter->first.age << endl;
        }
    
        return 0;
    }
    
    Output:
    Tom1    20
    Tom3    22
    Tom4    23
    Tom5    24
    
    operator< 的重载一定要定义成const。因为map内部实现时调用operator<的函数是const的。

    由于operator<比较的只是age,所以因为Tom2和Tom3的age相同,所以最终结果里面只有Tom3,没有Tom2

     
     
    boost::unordered_map
     
    #include<string>  
    #include<iostream>  
    #include<boost/unordered_map.hpp>
    using namespace std;  
      
    struct person  
    {  
        string name;  
        int age;  
      
        person(string name, int age)  
        {  
            this->name =  name;  
            this->age = age;  
        }  
      
        bool operator== (const person& p) const  
        {  
            return name==p.name && age==p.age;  
        }  
    };  
      
    size_t hash_value(const person& p)  
    {  
        size_t seed = 0;  
        boost::hash_combine(seed, boost::hash_value(p.name));  
        boost::hash_combine(seed, boost::hash_value(p.age));  
        return seed;  
    }  
      
    int main()  
    {  
        typedef boost::unordered_map<person,int> umap;  
        umap m;  
        person p1("Tom1",20);  
        person p2("Tom2",22);  
        person p3("Tom3",22);  
        person p4("Tom4",23);  
        person p5("Tom5",24);  
        m.insert(umap::value_type(p3, 100));  
        m.insert(umap::value_type(p4, 100));  
        m.insert(umap::value_type(p5, 100));  
        m.insert(umap::value_type(p1, 100));  
        m.insert(umap::value_type(p2, 100));  
          
        for(umap::iterator iter = m.begin(); iter != m.end(); iter++)  
        {  
            cout<<iter->first.name<<"	"<<iter->first.age<<endl;  
        }  
          
        return 0;  
    }
    
    Output:
    Tom1    20
    Tom5    24
    Tom4    23
    Tom2    22
    Tom3    22 
    注:上例需要有boost库的支持
    必须要自定义operator==和hash_value。 重载operator==是因为,如果两个元素的hash_value的值相同,并不能断定这两个元素就相同,必须再调用operator==。 当然,如果hash_value的值不同,就不需要调用operator==了。
  • 相关阅读:
    [CF1284E]New Year and Castle Construction
    [BZOJ2178]圆的面积并(格林公式)
    [CF1146H]Satanic Panic(dp)
    [CF1019D]Large Triangle
    [ICPC World Finals 2018][LOJ6409]熊猫保护区(voronoi图)
    [CF gym 101471A][LOJ6470]Airport Construction
    [BZOJ2809]dispatching(左偏树)
    [HDU5784]How Many Triangles
    [CF372E]Drawing circles is fun(反演)
    [NOI2005][BZOJ1502][洛谷P4207]月下柠檬树(自适应Simpson积分)
  • 原文地址:https://www.cnblogs.com/ZhaoxiCheung/p/7291702.html
Copyright © 2011-2022 走看看