适合中文关键字的哈希函数

hash函数的策略。 

    对于GB2312编码,设输入的汉字为GBword,我们可以采用公式(C1-176)*94 + (C2-161)确定GBindex。其中,C1表示第一字节,C2表示第二字节。具体如下: 

    GBindex = ((unsigned char)GBword.at(0)-176)*94 + (unsigned char)GBword.at(1) - 161; 

    之所以用unsigned char类型,是因为char是一个字节,如果用unsigend int,因为int是4个字节的,所以会造成扩展,导致错误。 

       对于GBK编码,设输入的汉字为GBKword,则可以采用公式   index=(ch1-0x81)*190+(ch2-0x40)-(ch2/128),其中ch1是第一字节,ch2是第二字节。 

    具体的, 

    GBKindex = ((unsigned char)GBKword[0]-129)*190 +  ((unsigned char)GBKword[1]-64) - (unsigned char)GBKword[1]/128; 

哈希表的性能很大程度上取决于一个哈希函数的好坏。我用单个汉字作为key,5702个汉字冲突率为0,quite impressive。



例如一个 对单个GBK汉字的哈希函数可以这么写:

struct hash_CHGBK{
	size_t operator()(const char* GBKword) const{
		size_t GBKindex;
		GBKindex = ((unsigned char)GBKword[0]-129)*190 +
               ((unsigned char)GBKword[1]-64) - (unsigned char)GBKword[1]/128;
	}
};

加上一个比较的函数:

struct eqstr
{
	bool operator()(const char* s1, const char* s2)const{
		return strcmp(s1, s2)==0;
	};
};

可以这么用

hash_map<const char*, int, hash_CHGBK, eqstr> CHGBK_hashmap;




原帖地址:http://www.iteye.com/problems/60530

原帖作者:deepfuture 


hash函数列表

https://www.byvoid.com/blog/string-hash-compare/

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
构建哈希表的过程可以分为以下几个步骤: 1. 设定哈希函数哈希函数关键字映射到散列地址上。常用的哈希函数包括取模法、乘法哈希法、除留余数法等。选择哈希函数时需要考虑关键字的特点,以及散列地址的分布情况。一个好的哈希函数应该能够将关键字均匀地分布在散列地址空间中,避免冲突的发生。 2. 分配散列地址空间:根据哈希函数的返回值,将关键字分配到散列地址空间中。通常,散列地址空间是一个固定大小的数组,每个元素对应一个散列地址。 3. 解决冲突:由于哈希函数的值域通常比关键字集合的基数要小,因此会出现多个关键字被映射到同一个散列地址的情况,即发生了冲突。解决冲突的方法包括开放地址法、链地址法、再哈希法、建立公共溢出区等。其中,链地址法是最常用的解决冲突的方法。在链地址法中,每个散列地址上维护一个链表,将所有映射到该地址上的关键字存储在链表中。 4. 插入关键字:将关键字插入到对应的散列地址中。如果发生冲突,根据选择的解决冲突方法,在对应散列地址上的链表中插入该关键字即可。 5. 查找关键字:根据哈希函数计算出关键字的散列地址,在对应散列地址上的链表中查找该关键字即可。 总的来说,构建哈希表需要选择合适的哈希函数、解决冲突的方法,以及分配散列地址空间和插入、查找关键字的具体实现。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值