第一種用法:(SGI STL中,linux中g++採用此種STL標準)
#include <ext/hash_map>
using namespace __gnu_cxx;
已經定義的hash Function:struct hash<char*>
struct hash<const char*>
struct hash<char>
struct hash<unsigned char>
struct hash<signed char>
struct hash<short>
struct hash<unsigned short>
struct hash<int>
struct hash<unsigned int>
struct hash<long>
struct hash<unsigned long>
第二種用法:(boost STL中)#include <unordered_map>
using namespace std::unordered_map;
已經定義了很多hash Function,除上述的hash Function外,還另外定義了struct hash<string>
二.hash_map的原型
template <class _Key, class _Tp, class _HashFcn = hash<_Key>,//hash函數
class _EqualKey = equal_to<_Key>,//比較函數
class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) >//allocator
class hash_map
{
...
}
hash_map<int, string> mymap;
//等同於:
hash_map<int, string, hash<int>, equal_to<int> > mymap;
當然在unordered_map中定義如下:
unordered_map<int, string> mymap;
使用時可根據需要自定義hash Function和equal Key三.自定義比較函數和hash函數
3.1自定義hash Function
在聲明自己的哈希函數時要注意以下幾點:
使用struct,然後重載operator().
返回是size_t
參數是你要hash的key的類型。
函數是const類型的。
例子:
自定義hash規則
struct str_hash{
size_t operator()(const string& str) const
{
unsigned long __h = 0;
for (size_t i = 0 ; i < str.size() ; i ++)
__h = 5*__h + str[i];
return size_t(__h);
}
};
//利用系統自定義的struct hash<char*>來自定義自己的hash Function object
struct str_hash{
size_t operator()(const string& str) const
{
return __stl_hash_string(str.c_str());
}
};
在聲明自己的哈希函數時要注意以下幾點:(function object)使用struct,然後重載operator().
返回是size_t
參數是你要hash的key的類型。
函數是const類型的(重要,不能丟失const,否則無法導入到stl中會出現編譯錯誤)
注意點:在hash_map中自定義hash Function和equalKey時,均不能丟失const
對於使用SGI STL的用戶,由於struct hash<string>系統未提供,所以需要自己定義。
如果使用boost STL的用戶,則基本上不需要自定義hash Function,除非想對比較複雜的對象類型定義hash 索引
3.2自定義equal Key
自定義equal Key有兩種方法:
3.2.1重載==操作符
struct mystruct{
int iID;
int len;
bool operator==(const mystruct & my) const{
return (iID==my.iID) && (len==my.len) ;
}
};
3.2.2 使用函數對象
struct compare_str{
bool operator()(const char* p1, const char*p2) const{
return strcmp(p1,p2)==0;
}
};
四.小總結添加頭文件與相應的命名空間
自定義hash Function(使用函數對象)
自定義equal Key(重載==操作符或者運用函數對象)
五.例子
代碼如下:
#include <iostream>
#include <unordered_map>
#include <string>
#include <algorithm>
using std::cin;
using std::cout;
using std::endl;
using std::string;
using std::sort;
using std::unordered_map;
using std::string;
const int N = 1003;
class myClass{
private:
string name;
int id;
public:
string getString() const { return name; }
int getID() const {return id; }
myClass(string _name, int _id):name(_name), id(_id) {}
/*bool operator==(const myClass &_myclass){
return getString() == _myclass.getString() && getID() == _myClass.getID();
}*/
};
////SGI STL中運用系統自帶的__stl_hash_string函數定義自己的hash Function
////boost STL中怎麼引用系統自帶的hash函數?
//struct hashFun{
// size_t operator()(const myClass &m) const {
// return __stl_hash_string(m.c_str());
// }
//}
//自定義hash Function
struct hashFun{
size_t operator()(const myClass& m) const
{
unsigned long __h = 0;
string tStr = m.getString();
for (size_t i = 0 ; i < tStr.size() ; i ++)
__h = 5*__h + tStr[i];
return size_t(__h);
}
};
struct equalKey{
bool operator()(const myClass &m1, const myClass m2) const {
return m1.getString() == m2.getString() && m1.getID() == m2.getID();
}
};
int main(){
freopen("./output.txt", "w", stdout);
unordered_map<myClass, int, hashFun, equalKey> uMap;
for(int i = 0; i < N; i++){
string tName = "cjw";
char ss[10];
string tmp;
sprintf(ss, "%d", i);
tmp = ss;
tName = tName + tmp;
myClass tClass(tName, i);
uMap[tClass] = i * 2;
}
for(unordered_map<myClass, int, hashFun, equalKey>::iterator ite = uMap.begin(); ite != uMap.end(); ite++){
cout << ite->first.getString() << " " << ite->first.getID() << " " << ite->second << endl;
}
}