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;
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值