C++ 散列函数及其工作方式

C++ 散列函数及其工作方式,c++,hash,C++,Hash,所以我有两种不同的字段类型,一种是长度为n的char*字段,另一种是int字段。我添加int变量的最后16位,我们将调用sum integer x,然后使用collate:hash为char*生成一个hashvalue,我们将其称为integer y。然后我将x+y加在一起,然后使用散列和总和生成散列值。假设我想将hashvalue限制在[1,4]的范围内。我可以通过哈希值%4得到我想要的吗?另外,如果有更好的方法从两个键生成hashvalue,请告诉我 对于[1,4]范围,必须将1添加到哈希值

所以我有两种不同的字段类型,一种是长度为n的char*字段,另一种是int字段。我添加int变量的最后16位,我们将调用sum integer x,然后使用collate:hash为char*生成一个hashvalue,我们将其称为integer y。然后我将x+y加在一起,然后使用散列和总和生成散列值。假设我想将hashvalue限制在[1,4]的范围内。我可以通过哈希值%4得到我想要的吗?另外,如果有更好的方法从两个键生成hashvalue,请告诉我

对于[1,4]范围,必须将1添加到
哈希值%4
。然而,4的散列是一个非常小的散列。这将导致大量冲突,限制哈希的有效性(即,字段的许多不同值将为您提供相同的哈希值)

我建议您在散列中添加更多的大小(位),可能是64K(16位散列)。这将减少碰撞。另外,为什么不使用已经实现了哈希表的
std::unordered_map


最后,根据散列函数,它取决于每个字段的含义。例如,如果在您的实现中,只有整数的低16位计数,那么散列应该仅基于这些位。有用于字符串和整数的通用哈希函数,因此您可以使用其中的任何一种。最后,为了组合这两个字段的散列值,求和(或异或)是一种常见的方法。只需确保生成的哈希值尽可能均匀地分布在整个范围内。

因此,您用许多词描述的内容如下:

struct noname {
  int ifield;
  char[N] cfield;
};

int hash(const noname &n) {
  int x = n.ifield;
  int y = ???(n.cfield);
  return x + y;
  // return (x + y) & 3;
}
此哈希函数是否良好取决于数据。例如,如果
ifield
始终是4的倍数,则显然是错误的。如果字段的值大致均匀分布,则一切正常

好的,除了您要求将散列范围限制为
[1;4]
之外。首先,
[0;3]
更容易计算,其次,如果您只有两到三个不同的对象将生成它们的哈希代码,那么这样一个小的范围是合适的。范围应至少是预期不同元素数量的两倍