发布时间:2022-07-05 文章分类:编程知识 投稿人:赵颖 字号: 默认 | | 超大 打印

STL map与Boost unordered_map

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

|字号订阅


分类:C++2011-12-24 11:05311人阅读评论(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 plaincopy

#include<string>
#include<iostream>
#include<map>

usingnamespacestd;

structperson
{
stringname;
intage;

person(stringname,intage)
{
this->name=name;
this->age=age;
}

booloperator<(constperson&p)const
{
returnthis->age<p.age;
}
};

map<person,int>m;
intmain()
{
personp1("Tom1",20);
personp2("Tom2",22);
personp3("Tom3",22);
personp4("Tom4",23);
personp5("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>::iteratoriter=m.begin();iter!=m.end();iter++)
{
cout<<iter->first.name<<"\t"<<iter->first.age<<endl;
}

return0;
}

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 plaincopy

#include<string>
#include<iostream>

#include<boost/unordered_map.hpp>

usingnamespacestd;

structperson
{
stringname;
intage;

person(stringname,intage)
{
this->name=name;
this->age=age;
}

booloperator==(constperson&p)const
{
returnname==p.name&&age==p.age;
}
};

size_thash_value(constperson&p)
{
size_tseed=0;
boost::hash_combine(seed,boost::hash_value(p.name));
boost::hash_combine(seed,boost::hash_value(p.age));
returnseed;
}

intmain()
{
typedefboost::unordered_map<person,int>umap;
umapm;
personp1("Tom1",20);
personp2("Tom2",22);
personp3("Tom3",22);
personp4("Tom4",23);
personp5("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::iteratoriter=m.begin();iter!=m.end();iter++)
{
cout<<iter->first.name<<"\t"<<iter->first.age<<endl;
}

return0;
}
输出

Tom1 20
Tom5 24
Tom4 23
Tom2 22
Tom3 22

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