(转)STL map与Boost unordered_map

转:http://blog.csdn.net/orzlzro/article/details/7099231

今天看到 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

#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

#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==了。

时间: 2024-10-10 14:05:19

(转)STL map与Boost unordered_map的相关文章

(转载)STL map与Boost unordered_map的比较

原链接:传送门 今天看到 boost::unordered_map,它与 stl::map的区别就是,stl::map是按照operator<比较判断元素是否相同,以及比较元素的大小,然后选择合适的位置插入到树中.所以,如果对map进行遍历(中序遍历)的话,输出的结果是有序的.顺序就是按照operator< 定义的大小排序.而boost::unordered_map是计算元素的Hash值,根据Hash值判断元素是否相同.所以,对unordered_map进行遍历,结果是无序的. 用法的区别就是

boost::unordered_map 和 std::map 的效率 与 内存比较

例子链接:http://blog.csdn.net/gamecreating/article/details/7698719 结论: unordered_map 查找效率快五倍,插入更快,节省一定内存.如果没有必要排序的话,尽量使用 hash_map(unordered_map 就是 boost 里面的 hash_map 实现). boost::unordered_map 和 std::map 的效率 与 内存比较

正确使用stl map的find,erase方法

查找某个key对应的value的方法,有2种: 方法1: typedef std::multimap<boost::uint64_t,std::string>::iterator it it = mmap_.find( nCallLetter ); if ( it != mmap_.end()) { char key[20] = {0}; sprintf(key, "%I64d",it->first); qDebug("key = %s,value = %s

C++ STL map(映射)

头文件:#include<map>,当然,万能库就不用我多说了吧.. 介绍:map容器是一个键 (key) 到值 (value) 的映射.因为重载了 [ ] 运算符,map像是数组的"高级版".map的key和value可以是任意类型,其中key必须定义"小于号"运算符.例如可以用一个map <string,int> month_name 来表示"月份名字到月份编号"的映射,然后用month_name["July

stl::map之const函数访问

如何在const成员数中访问stl::map呢?例如如下代码: string ConfigFileManager::MapQueryItem(const string& name) const { if (_map_name_value.find(name) != _map_name_value.end()) { return _map_name_value[name]; } return ""; } 上面的代码会报错:error C2678: 二进制“[”: 没有找到接受“c

hdu 4941 Magical Forest(STL map &amp; 结构体运用)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4941 Magical Forest Time Limit: 24000/12000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 220    Accepted Submission(s): 105 Problem Description There is a forest c

ZOJ1109_Language of FatMouse(STL/map)

解题报告 题意: 略. 思路: map应用. #include <algorithm> #include <iostream> #include <cstring> #include <cmath> #include <queue> #include <vector> #include <cstdio> #include <map> using namespace std; map<string,stri

POJ训练计划3096_Surprising Strings(STL/map)

解题报告 题目传送门 题意: 给一个字符串,要求,对于这个字符串空隔为k取字符对(k=0,1,2,3,4...)要求在相同的空隔取对过程汇总,整个字符串中没有一个相同字符对如: ZGBZ: 间隔为0的字符对有: ZG.GB.BZ,三个均不相同 间隔为1的字符对有: ZG. GZ,均不相同 间隔为2的字符对有: ZZ 仅有一个,不必比较. 这种字符串定义为"surprising". 之后按照格式输出. 思路: map暴力. #include <iostream> #inclu

支持泛型AVL Tree的简单实现,并和STL map比较了插入,删除,查找的性能

1.问题描述: 1)AVL tree是一种自平衡树.它通过左右子树的高度差来控制树的平衡,当高度差是不大于1的时候,认为树是平衡的.树的平衡保证了树在极端情况下 (输入序列不够随机)的性能.很显然当左右子树高度平衡,保证了任何插入,删除,查找操作平均性能呢个,当不平衡时(有的子树很高),当 要操作的元素在这个子树时,性能会很差: 2)AVL tree 和Red black tree 都是一种平衡树,它的操作的时间复杂度是:O(lgN) ,N是树的节点的数目: 3)本文实现了AVL Tree, 并