今天看到
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 plaincopyprint?
#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;
}
#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 plaincopyprint?
#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;
}
#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==了。
声明:本站所有文章 ,如无特殊说明或标注 ,均为本站原创发布 。任何个人或组织 ,在未征得本站同意时,禁止复制 、盗用 、采集 、发布本站内容到任何网站 、书籍等各类媒体平台 。如若本站内容侵犯了原著者的合法权益 ,可联系我们进行处理 。