Data structures 什么哈希函数;“黑客”;你用什么?

Data structures 什么哈希函数;“黑客”;你用什么?,data-structures,hash,hashmap,hashtable,hashcode,Data Structures,Hash,Hashmap,Hashtable,Hashcode,散列函数可以依赖于数据。例如(来自文章)如果您的数据都是字符串,并且几乎所有的字符串都具有不同的长度,那么简单的字符串长度可能是一个非常好的哈希函数(我知道这不太现实)。或者,例如,从0到1的实数可以有一个简单的哈希函数: 值*sizeOfHashTable 我很感兴趣,如果你使用这样的哈希函数,是专门为您的输入?还有其他示例吗?正如您正确指出的,哈希函数依赖于哈希数据。 设计一个好的散列函数的一般想法-遵守3个条件: 函数必须易于计算。也许,最好使用不太好的散列,但计算速度快,并且比在不平衡

散列函数可以依赖于数据。例如(来自文章)如果您的数据都是字符串,并且几乎所有的字符串都具有不同的长度,那么简单的字符串长度可能是一个非常好的哈希函数(我知道这不太现实)。或者,例如,从0到1的实数可以有一个简单的哈希函数:

值*sizeOfHashTable


我很感兴趣,如果你使用这样的哈希函数,是专门为您的输入?还有其他示例吗?

正如您正确指出的,哈希函数依赖于哈希数据。 设计一个好的散列函数的一般想法-遵守3个条件:

  • 函数必须易于计算。也许,最好使用不太好的散列,但计算速度快,并且比在不平衡的存储桶或表路径上丢失的数据节省更多的散列时间

  • 函数在测试数据集上必须具有良好的分布(伪随机)。好主意-在哈希函数中使用“雪崩效应”,当更改输入数据中的一个位时,会更改输出值中的半个位

  • 对于外部输入数据,哈希函数必须是“通用”的,即抵抗尝试生成冲突

我最喜欢的哈希函数如下。首次使用前,需要使用一些随机值初始化表S_块。在每次程序运行时都这样做是个好主意

const unsigned int S_block[256] = { ... };
#define NLF(h, c) (S_block[(unsigned char)(c + h)] ^ c)

unsigned int hash(const char *key) {
unsigned int h = 0x1F351F35;
char c;
while(c = *key++)
  h = ((h << 7) | (h >> (32 - 7))) + NLF(h, c);
h ^= h >> 16;
return h ^ (h >> 8);
}
const unsigned int S_块[256]={…};
#定义NLF(h,c)(S_块[(无符号字符)(c+h)]^c)
无符号整数散列(常量字符*键){
无符号整数h=0x1F351F35;
字符c;
而(c=*key++)
h=((h>(32-7))+NLF(h,c);
h^=h>>16;
返回h^(h>>8);
}

作为实际示例,请参见在“我的程序”中使用此函数的变体。该文件包含此函数的变体,适用于该算法。

这些类型的“黑客”通常不有用。它们在特殊情况下工作,但在一般情况下,它们会遇到这样或那样的问题。例如,当输入值的范围非常小时,实数情况可能非常糟糕。因为许多数字将解析为相同的哈希值。我投票决定结束这个例子,因为它太宽泛了。实数例子会有问题,如果输入不是均匀分布的,那么对于随机输入就可以了。范围已定义-0到1。使用这种“黑客”的唯一原因是速度。