STL map與Boost unordered_map - orzlzro的專欄 - 博客頻道 - CSDN.NET
今天看到? boost::unordered_map, 它與 stl::map的區(qū)別就是,stl::map是按照operator<比較判斷元素是否相同,以及比較元素的大小,然后選擇合適的位置插入到樹中。所以,如果對(duì)map進(jìn)行遍歷(中序遍歷)的話,輸出的結(jié)果是有序的。順序就是按照operator<
定義的大小排序。而boost::unordered_map是計(jì)算元素的Hash值,根據(jù)Hash值判斷元素是否相同。所以,對(duì) unordered_map進(jìn)行遍歷,結(jié)果是無序的。
用法的區(qū)別就是,stl::map 的key需要定義operator< 。 而boost::unordered_map需要定義hash_value函數(shù)并且重載operator==。對(duì)于內(nèi)置類型,如string,這些都不用操心。對(duì)于自定義的類型做key,就需要自己重載operator<
或者h(yuǎn)ash_value()了。?
最后,說,當(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;??
- }??
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,沒有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;??
- }??
輸出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==了。
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
