我在过去做了一个关于哈希表的小练习,但是用户给出了数组大小,结构也是这样的(因此用户每次都给出一个数字和一个单词作为输入)
struct data
{
int key;
char c[20];
};
所以这很简单,因为我知道数组大小,并且用户也说他将提供多少项作为输入。我这样做的方式是
但现在我必须制作倒排索引,我正在重新研究,所以我可以为它制作一个哈希表。因此,这些单词将从大约30个字节收集,并且它们将是如此之多。 那么在这种情况下阵列需要多长时间?我怎么哈希的话?我应该使用开放地址或链接的哈希。练习sais我们可以使用哈希表,如果我们在网上找到它。但我更喜欢自己理解并创造它。任何线索都会帮助我:)。
在这个exerice中(使用哈希表的反向索引)结构看起来像这样。 data type是我将创建的哈希表的类型。
struct posting
{
string word;
posting *next
}
struct data
{
string word;
posting *ptrpostings;
data *next
};
答案 0 :(得分:3)
无论如何,你可以选择哈希。假设字符串是ABC。你可以使用散列作为A = 1,B = 2,C = 3,Hash = 1 + 2 + 3 /(length = 3)= 2.但是,这是非常原始的。
数组的大小取决于您部署的哈希算法,但最好选择一种为每个字符串返回确定长度哈希值的算法。例如,如果选择使用SHA1,则可以安全地为每个哈希分配40个字节。请参阅Storing SHA1 hash values in MySQL阅读算法http://en.wikipedia.org/wiki/SHA-1。我相信它可以安全使用。
另一方面,如果只是为了一个简单的练习,你也可以使用MD5哈希。我不建议在实际应用中使用它,因为它的彩虹表很容易获得:)
--------- EDIT -------
您可以尝试像这样实现::
#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;
}
然后,要实现O(1),只要你想获取文件名的内容,只需运行returnHash(filename)函数即可。它将直接返回数组的索引:)
答案 1 :(得分:1)
哈希表可以实现为简单的二维数组。问题是如何计算要存储的每个项目的唯一键。有些东西会在数据中加入密钥,而对于其他东西你需要计算一个:上面建议的MD5可能只是满足你的需求。
您需要解决的下一个问题是如何布局或调整哈希表的大小。这是你最终需要通过一些测试来调整自己需求的东西。您可以首先使用255个条目设置数组的第一个维度 - 对于MD5哈希的前两个数字的每个组合一个。每当发生碰撞时,都会在第一维索引处沿阵列的第二维添加另一个条目。这意味着您将静态定义一维数组,同时根据需要动态分配第二维项。希望这对你来说和对我一样有意义。
进行查找时,您可以使用MD5哈希的第一个2位数立即找到正确的第一维索引。然后沿着第二维度的相对线短线性搜索将很快带您到您寻找的项目。
如果您的数据集足够大,您可以从实验中发现使用更大的第一维(使用MD5哈希的fisrt 3位)更有效。根据所涉及文本的大小和词汇使用的分布,您的结果可能会决定您的一些架构。
另一方面,您可能只是从小处开始并构建一些智能来自动调整大小和布局表格。如果你的桌子在任何一个方向上都太长,性能就会受到影响。