今天看到 boost::unordered_map, 它與 stl::map的區(qū)別就是,stl::map是按照operator<比較判斷元素是否相同,以及比較元素的大小,然后選擇合適的位置插入到樹(shù)中。所以,如果對(duì)map進(jìn)行遍歷(中序遍歷)的話,輸出的結(jié)果是有序的。順序就是按照operator< 定義的大小排序。
而boost::unordered_map是計(jì)算元素的Hash值,根據(jù)Hash值判斷元素是否相同。所以,對(duì)unordered_map進(jìn)行遍歷,結(jié)果是無(wú)序的。
用法的區(qū)別就是,stl::map 的key需要定義operator< 。 而boost::unordered_map需要定義hash_value函數(shù)并且重載operator==。對(duì)于內(nèi)置類型,如string,這些都不用操心。對(duì)于自定義的類型做key,就需要自己重載operator< 或者h(yuǎn)ash_value()了。
最后,說(shuō),當(dāng)不需要結(jié)果排好序時(shí),最好用unordered_map。
其實(shí),stl::map對(duì)于與java中的TreeMap,而boost::unordered_map對(duì)應(yīng)于java中的HashMap。
stl::map
- #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;
- }
#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。因?yàn)閙ap內(nèi)部實(shí)現(xiàn)時(shí)調(diào)用operator<的函數(shù)好像是const。
由于operator<比較的只是age,所以因?yàn)門om2和Tom3的age相同,所以最終結(jié)果里面只有Tom3,沒(méi)有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<<"\t"<<iter->first.age<<endl;
- }
- return 0;
- }
#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==是因?yàn)椋绻麅蓚€(gè)元素的hash_value的值相同,并不能斷定這兩個(gè)元素就相同,必須再調(diào)用operator==。 當(dāng)然,如果hash_value的值不同,就不需要調(diào)用operator==了。