STL map与Boost unordered_map - 有何不可的日

系统 1945 0

STL map与Boost unordered_map - 有何不可的日志 - 网易博客

STL map与Boost unordered_map     

 

2012-03-30 16:06:26 |  分类:
c|c++
|  标签:  

| 字号     订阅


分类:  C++ 2011-12-24 11:05 311人阅读  评论 (0) 收藏  举报

今天看到 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。

 

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

 

stl::map

 


[cpp]  view plain copy

#include<string>  
#include<iostream>  
#include<map>  
  
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<<"\t"<<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

 


[cpp]  view plain copy

#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<<"\t"<<iter->first.age<<endl;  
    }  
      
    return 0;  
}  
输出

 

Tom1    20
Tom5    24
Tom4    23
Tom2    22
Tom3    22

 

必须要自定义operator==和hash_value。 重载operator==是因为,如果两个元素的hash_value的值相同,并不能断定这两个元素就相同,必须再调用operator==。 当然,如果hash_value的值不同,就不需要调用operator==了。

STL map与Boost unordered_map - 有何不可的日志 - 网易博客


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论