我需要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;)'
由于
答案 0 :(得分:8)
您的问题是hash<T>
仅适用于某些类型。它不能神奇地为任何旧类型创建哈希函数。你需要自己创建哈希函数。
答案 1 :(得分:6)
首先,您需要std::unordered_map
或unordered_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;)将对象传递给比较器函数。当传递它时,每次进行比较时,都会执行昂贵的内存分配和字符串副本,从而浪费时间和内存。