如何在STL中使用unordered_set?

时间:2009-11-30 03:22:14

标签: c++ stl

我需要C ++(STL)中的hash_map类。主要操作是将对放入集合中,然后检查它是否存在。

我无法找到一个示例代码来了解我是否正确声明了什么。

#include <iostream>
#include <hash_map>

using namespace std;
using namespace __gnu_cxx;

typedef pair<int,string> pis;

struct eqpis {
    bool operator()(pis p1,pis p2) const {
        if(p1==p2) return true;
        return false;
    }
};

int main() {
    hash_map<pis,int,hash<pis>,eqpis> map;
}    

这个编译。但是,如果我添加该行:     地图[PIS(10, “你好”)] = 10; 然后它会产生很多错误:

/ usr / include / c ++ / 4.4 / backward / hashtable.h:在成员函数'size_t __gnu_cxx :: hashtable :: _ M_bkt_num_key(const _Key&amp;,size_t)const [with _Val = std :: pair,std ::分配器&gt; &gt;,int&gt ;,_Key = std :: pair,std :: allocator&gt; &gt;,_ HashFcn = __gnu_cxx :: hash,std :: allocator&gt; &GT; &gt;,_ ExtractKey = std :: _ Select1st,std :: allocator&gt; &gt;,int&gt; &gt;,_ EqualKey = eqpis,_Alloc = std :: allocator]': /usr/include/c++/4.4/backward/hashtable.h:594:从'size_t __gnu_cxx :: hashtable :: _ M_bkt_num(const _Val&amp;,size_t)const [与_Val = std :: pair,std :: allocator&gt]实例化; &gt;,int&gt ;,_Key = std :: pair,std :: allocator&gt; &gt;,_ HashFcn = __gnu_cxx :: hash,std :: allocator&gt; &GT; &gt;,_ ExtractKey = std :: _ Select1st,std :: allocator&gt; &gt;,int&gt; &gt;,_ EqualKey = eqpis,_Alloc = std :: allocator]' /usr/include/c++/4.4/backward/hashtable.h:1001:从'void __gnu_cxx :: hashtable :: resize(size_t)实例化[与_Val = std :: pair,std :: allocator&gt; &gt;,int&gt ;,_Key = std :: pair,std :: allocator&gt; &gt;,_ HashFcn = __gnu_cxx :: hash,std :: allocator&gt; &GT; &gt;,_ ExtractKey = std :: _ Select1st,std :: allocator&gt; &gt;,int&gt; &gt;,_ EqualKey = eqpis,_Alloc = std :: allocator]' /usr/include/c++/4.4/backward/hashtable.h:789:从'_Val&amp; __gnu_cxx :: hashtable :: find_or_insert(const _Val&amp;)[with _Val = std :: pair,std :: allocator&gt; &gt;,int&gt ;,_Key = std :: pair,std :: allocator&gt; &gt;,_ HashFcn = __gnu_cxx :: hash,std :: allocator&gt; &GT; &gt;,_ ExtractKey = std :: _ Select1st,std :: allocator&gt; &gt;,int&gt; &gt;,_ EqualKey = eqpis,_Alloc = std :: allocator]' /usr/include/c++/4.4/backward/hash_map:216:从'_Tp&amp;中实例化__gnu_cxx :: hash_map :: operator [](const typename __gnu_cxx :: hashtable,_Key,_HashFn,std :: _ Select1st&gt;,_EqualKey,_Alloc&gt; :: key_type&amp;)[with _Key = std :: pair,std :: allocator &GT; &gt;,_ Tp = int,_HashFn = __gnu_cxx :: hash,std :: allocator&gt; &GT; &gt;,_ EqualKey = eqpis,_Alloc = std :: allocator]' x.cpp:18:从这里实例化 /usr/include/c++/4.4/backward/hashtable.h:590:错误:无法调用'(const __gnu_cxx :: hash,std :: allocator&gt;&gt;&gt;)(const std :: pair, std :: allocator&gt;&gt;&amp;)'

由于

5 个答案:

答案 0 :(得分:8)

您的问题是hash<T>仅适用于某些类型。它不能神奇地为任何旧类型创建哈希函数。你需要自己创建哈希函数。

答案 1 :(得分:6)

首先,您需要std::unordered_mapunordered_set。要求是您的类需要operator=(或者您需要一个EqualityCompare类),并且您需要一个具有operator()的散列类,它将您的键类型作为参数并返回size_t

答案 2 :(得分:2)

您以与std :: map:

相同的方式使用它
typedef hash_map<int,string> HMap;

HMap map;
map.insert(HMap::value_type(1,"two"));

for (HMap::iterator it = map.begin(); it != map.end(); ++it)
{
    cout << (*it).first << " " << (*it).second << endl;
}

windows和linux之间的头文件存在一些差异:

#ifdef WIN32
#include <hash_map>
#else
#include <ext/hash_map>
#endif

#ifndef WIN32
    using __gnu_cxx::hash_map;
#endif

#ifdef WIN32
    typedef hash_map< const K, V > HMap;
#else
    typedef hash_map< const K, V, boost::hash<K> >;
#endif

我相信linux hash_map需要哈希函数才能对键进行哈希处理,你可以使用上面的boost :: hash。

这是你在linux上编译的代码(参见上面的linux和windows之间的差异,我正在使用boost :: hash,因为在Linux上没有哈希函数,在windows中有一个,我不确定它是否是重载了struct type ...):

#include <iostream>
//#include <hash_map>
#include <ext/hash_map>
#include <string>
#include <boost/functional/hash.hpp>
using namespace std;
//using namespace __gnu_cxx;
using __gnu_cxx::hash_map;

typedef pair<int,string> pis;

struct eqpis {
    bool operator()(pis p1,pis p2) const {
        if(p1==p2) return true;
        return false;
    }
};

int main() {
    //hash_map<pis,int,hash<pis>,eqpis> map;
    typedef hash_map<pis,int, boost::hash<pis>, eqpis > HMap;
    HMap map;
    map.insert(HMap::value_type(pis(10,"hello"), 11));
    map.insert(HMap::value_type(pis(20,"hello"), 21));
    map.insert(HMap::value_type(pis(30,"hello"), 31));
    map.insert(HMap::value_type(pis(40,"hello"), 41));

    for (HMap::iterator it = map.begin(); it != map.end(); ++it)
    {
        cout << (*it).first.first << ":" << (*it).first.second
             <<  " == " << (*it).second << endl;
    }
}

输出:

40:hello == 41
20:hello == 21
10:hello == 11
30:hello == 31

答案 3 :(得分:1)

我不确定您使用的是哪种编译器,但是您是否看过这个Hash map (C++) Wikipedia listing

答案 4 :(得分:1)

很抱歉迟到了回复。如果我是你,我会通过引用(const pis&amp;)将对象传递给比较器函数。当传递它时,每次进行比较时,都会执行昂贵的内存分配和字符串副本,从而浪费时间和内存。