(轉載)STL map與Boost unordered_map的比較
阿新 • • 發佈:2017-08-05
combine 排序 spa using 比例 遍歷 tail include 不用
原鏈接:傳送門
今天看到 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 << "\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#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;
}
Output:
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的比較