Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 字符串的哈希函数_C++_String_Hash_Hashtable - Fatal编程技术网

C++ 字符串的哈希函数

C++ 字符串的哈希函数,c++,string,hash,hashtable,C++,String,Hash,Hashtable,我们目前正在处理我的类中的哈希函数。我们的讲师要求我们在互联网上使用一个哈希函数,与我们在代码中使用的两个进行比较 第一个: int HashTable::hash (string word) // POST: the index of entry is returned { int sum = 0; for (int k = 0; k < word.length(); k++) sum = sum + int(word[k]);

我们目前正在处理我的类中的哈希函数。我们的讲师要求我们在互联网上使用一个哈希函数,与我们在代码中使用的两个进行比较

第一个:

int HashTable::hash (string word)   
// POST: the index of entry is returned
{       int sum = 0;
        for (int k = 0; k < word.length(); k++)
            sum = sum + int(word[k]);
        return  sum % SIZE; 
}
int哈希表::哈希(字符串字)
//POST:返回条目的索引
{int sum=0;
for(int k=0;k
第二:

int HashTable::hash (string word)
{
   int seed = 131; 
   unsigned long hash = 0;
   for(int i = 0; i < word.length(); i++)
   {
      hash = (hash * seed) + word[i];
   }
   return hash % SIZE;
}
int哈希表::哈希(字符串字)
{
int-seed=131;
无符号长散列=0;
for(int i=0;i
其中大小为501(哈希表的大小),输入来自一个20000多字的文本文件

我通过一些代码示例看到了这个问题,但不确定在散列函数中要查找什么。如果我理解正确,在我的例子中,散列接受一个输入(字符串),并进行数学计算,为字符串分配一个数字,然后将其插入表中。执行此过程是为了提高搜索列表的速度

如果我的逻辑是正确的,那么有没有人有一个好的示例或资源来显示包含字符串的不同哈希函数?甚至是编写自己的高效散列函数的过程。

Java的:

比如说:

int HashTable::hash (string word) {
    int result = 0;
    for(size_t i = 0; i < word.length(); ++i) {
        result += word[i] * pow(31, i);
    }
    return result;
}
int哈希表::哈希(字符串字){
int结果=0;
对于(大小i=0;i
首先,在实践中它通常没有那么重要。大多数散列函数都“足够好”

但如果你真的在乎,你应该知道这本身就是一个研究课题。关于那件事有上千篇论文。今天,通过研究和设计哈希算法,你仍然可以获得博士学位

您的第二个散列函数可能稍好一些,因为它可能应该将字符串
“ab”
与字符串
“ba”
分开。另一方面,它可能不如第一个散列函数快。它可能与您的申请相关,也可能与您的申请无关

我猜用于基因组字符串的散列函数与电话数据库中用于散列姓氏的散列函数大不相同。也许甚至有些字符串哈希函数更适合德语,而不是英语或法语单词

许多软件库都提供了足够好的散列函数,例如Qt和C++11在
中都有,Glib在C中有几个,还有一些函数

我经常使用包含素数(参见)和xor的散列函数,例如

#define A 54059 /* a prime */
#define B 76963 /* another prime */
#define C 86969 /* yet another prime */
#define FIRSTH 37 /* also prime */
unsigned hash_str(const char* s)
{
   unsigned h = FIRSTH;
   while (*s) {
     h = (h * A) ^ (s[0] * B);
     s++;
   }
   return h; // or return h % C;
}
但我并不自称是散列专家。当然,
A
B
C
FIRSTH
的值最好是素数,但您可以选择其他素数

查看一些实现,了解散列函数可以是什么

大多数关于算法的好书至少有一整章专门讨论散列。从&.

上的wikipages开始,这是当今的发展方向--

unsigned int RSHash(const std::string& str)
{
    unsigned int b    = 378551;
    unsigned int a    = 63689;
    unsigned int hash = 0;

    for(std::size_t i = 0; i < str.length(); i++)
    {
        hash = hash * a + str[i];
        a    = a * b;
    }

    return (hash & 0x7FFFFFFF);
 }

 unsigned int JSHash(const std::string& str)
 {
      unsigned int hash = 1315423911;

      for(std::size_t i = 0; i < str.length(); i++)
      {
          hash ^= ((hash << 5) + str[i] + (hash >> 2));
      }

      return (hash & 0x7FFFFFFF);
 }
使用。为了保护你自己

--古老而危险--

unsigned int RSHash(const std::string& str)
{
    unsigned int b    = 378551;
    unsigned int a    = 63689;
    unsigned int hash = 0;

    for(std::size_t i = 0; i < str.length(); i++)
    {
        hash = hash * a + str[i];
        a    = a * b;
    }

    return (hash & 0x7FFFFFFF);
 }

 unsigned int JSHash(const std::string& str)
 {
      unsigned int hash = 1315423911;

      for(std::size_t i = 0; i < str.length(); i++)
      {
          hash ^= ((hash << 5) + str[i] + (hash >> 2));
      }

      return (hash & 0x7FFFFFFF);
 }
无符号整数RSHash(const std::string&str)
{
无符号整数b=378551;
无符号整数a=63689;
无符号整数散列=0;
对于(std::size_t i=0;i2));
}
返回值(散列&0x7FFFFFFF);
}

向谷歌咨询“通用哈希函数”

用于算法的哈希函数通常有两个目标,第一个目标是速度快,第二个目标是在可能的数字中均匀分布值。哈希函数还需要为相同的输入值提供所有相同的数字

如果您的值是字符串,下面是一些错误哈希函数的示例:

  • 字符串[0]
    -ASCII字符a-Z比其他字符更常见
  • string.lengh()
    -最可能的值是1
  • 好的散列函数尝试使用输入的每一位,同时使计算时间保持最少。如果您只需要一些散列码,请尝试将字节与素数相乘,然后求和。

    使用


    你的问题只提供了两个答案。如果你的讲师没有教你任何关于哈希表/函数的知识,他怎么能要求你分析两个哈希函数?“有人有好的示例或资源吗?”另请参见我认为java使用克利夫尔移位来计算该值,而不是直接计算表达式。31=32-1,所以31^k=(32-1)^k=(-1)^k+2*32*(-1)^(k-1)。。。32^k;因为32=2^5,32^7>sizeof(int),所以您只需要计算总和的前6个,甚至可以通过移位来完成。这比使用pow()要快,所以除非您愿意优化一些计算,否则不要这样做。这是一个非常好的答案+1 ... :)在Linux上,
    #include
    指令中的反斜杠不太可能工作,因此您的代码可能是特定于Windows的(或者您应该将反斜杠更改为斜杠)。这是一个关于散列概念的学术问题,因此没有任何用处。
    #include <boost\functional\hash.hpp>
    
    std::string a = "ABCDE";
    size_t b = boost::hash_value(a);