c++中字符串的哈希表

hash table for strings in c++

本文关键字:哈希表 字符串 c++      更新时间:2023-10-16

我以前做过一个关于哈希表的小练习但是用户给出了数组大小并且结构是这样的(所以用户每次输入一个数字和一个单词)

struct data
{
   int key;
   char c[20];
};

所以这是相当简单的,因为我知道数组的大小,而且用户说他会给多少项作为输入。我的做法是

  • 散列用户给我的密钥
  • 查找数组
  • 中的位置数组[hash (key)]
  • 如果它是空的,我将把数据放在那里
  • 如果不是,我会把它放在我找到的下一个空闲位置。

但是现在我必须做倒排索引,我正在研究,所以我可以为它做一个哈希表。因此,这些单词将从大约30条文本中收集,它们将是如此之多。在这种情况下,数组应该有多长?我怎么能散列单词?我应该使用开放地址还是链接。这个练习说明,如果我们在网上找到一个哈希表,我们就可以使用它。但我更喜欢自己去理解和创造它。任何线索都会对我有所帮助:)

在这个练习中(使用哈希表的倒排索引),结构看起来是这样的。数据类型是我要创建的哈希表的类型。

struct posting
{
    string word;
    posting *next
}
struct data
{
    string word;
    posting *ptrpostings;
    data *next
};

您可以选择任何方式进行散列。假设字符串是ABC。您可以使用散列作为A=1, B=2, C=3, Hash =1 +2+3/(长度=3)=2。但是,这是非常原始的。

数组的大小将取决于您部署的哈希算法,但最好选择为每个字符串返回确定长度哈希的算法。例如,如果您选择使用SHA1,您可以安全地为每个哈希分配40字节。参考在MySQL中存储SHA1哈希值详细了解算法http://en.wikipedia.org/wiki/SHA-1。我相信它可以安全使用。

另一方面,如果只是为了简单的练习,也可以使用MD5散列。我不建议在实际用途中使用它,因为它的彩虹表很容易获得:)

--------- 编辑——

你可以尝试这样实现::

#include <iostream>
#include <string>
#include <stdlib.h>
#include <stdio.h>
#define MAX_LEN 30
using namespace std;
typedef struct
{
    string name; // for the filename
    ... change this to your specification
}hashd;
hashd hashArray[MAX_LEN]; // tentative
int returnHash(string s)
{
    // A simple hashing, no collision handled
    int sum=0,index=0;
    for(string::size_type i=0; i < s.length(); i++)
    {
        sum += s[i];
    }
    index = sum % MAX_LEN;
    return index;
}
int main()
{
    string fileName;
    int index;
    cout << "Enter filename        ::t" ;
    cin >> fileName;
    cout << "Enter filename is     ::t" + fileName << "n";
    index = returnHash(fileName);
    cout << "Generated index is ::t" << index << "n";
    hashArray[index].name = fileName;
    cout << "Filename in array    ::t" <<hashArray[index].name ;
    return 0;
}

然后,为了实现0(1),任何时候想要获取文件名的内容,只需运行returnHash(filename)函数。它将直接返回数组的索引:)

哈希表可以实现为一个简单的二维数组。问题是如何计算要存储的每个项的唯一键。有些东西在数据中内置了密钥,而对于其他东西,您必须计算一个:上面建议的MD5可能正好可以满足您的需求。

您需要解决的下一个问题是如何布局或大小哈希表。这是您最终需要通过一些测试来调整到您自己的需求的东西。您可以首先将数组的第一维设置为255个条目——MD5散列的前2位数字的每个组合对应一个条目。每当发生碰撞时,就在数组的第2维上,在第1维索引处添加另一个项。这意味着您将静态地定义一个一维数组,同时根据需要动态地分配第二维项。希望这对你和我来说都有意义。

查找时,您可以使用MD5散列的前两位数字立即找到正确的第一维索引。然后,沿着第二次元相对较短的线性搜索将很快带你到你要找的项目。

你可能会从实验中发现,如果你的数据集足够大,使用更大的第一维(使用MD5哈希的前3位)会更有效。根据所涉及的文本的大小和它们使用词典的分布,您的结果可能会决定您的一些体系结构。

另一方面,您可能只是从小处开始,并构建一些智能来自动调整表的大小和布局。如果您的表在任何一个方向上太长,性能都会受到影响。