STL之hash_map總結

一.需要加載的頭頭文件和命名空間
第一種用法:(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;
	}
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章