【问题标题】:Hashing structures in CC中的散列结构
【发布时间】:2011-12-31 19:23:17
【问题描述】:

所以我正在尝试实现一个哈希表,它将对包含单词的结构进行哈希处理。

结构将与此类似:

#ifndef HASHTABLE_H
#def HASHTABLE_H

typedef int (*HashFunctionT) (char* string, int upperbound);

struct node_
{
    char * word;
    struct node * next;
}
typedef struct node_ * node;

struct nodehash_
{
    int size;
    struct node * hash[100];
}
typedef struct nodehash_ * nodehash;

Hashtable createHashTable();
void addtohash(node list, nodehash hash);
#endif

我希望哈希函数可以像这样工作:

#include "hashtable.h"

int hashFunction(char *word, int hashTableSize)
{
    int length = strlen(word);
    int h = 0;
    int i;  
    for(i = 0; i<length; i++)
    {
        h=31 *h  + word[i];
    }
    return h % hashTableSize;
};

nodehash createHashtable()
{
    nodehash hashtable;    
    hashtable = malloc(sizeof(struct nodehash_));

    hashtable->size = 100;
    hashtable->hash = malloc(100 * sizeof (node));
    int i;   
    for (i = 0; i < hashtable->size; i++)
    {
            hashtable->table[i] = NULL;
    }
    return hashtable;
};

void addtohash(node list, nodehash hashtable)
{
    int nodehashnumber;
    nodehashnumber = hashfunction(list->word, hash->size);
    hashtable->hash[nodehasnumber] = list;
};

主函数看起来像这样(假设已经创建并填充了节点结构的链表)。

int main()
{
    nodehash hashtable = createhashtable();
    node nodelist;
    /* here the nodelist would be created and filled and such and such*/
    while (nodelist->next != NULL)
    {
        addtohash(nodelist, hashtable);
    }
    return;
}

假设不可能有冲突,因为每个要散列的单词都会不同。

基本上,我想知道我是否遗漏了明显的错误或逻辑缺陷。

任何帮助将不胜感激。

谢谢。

【问题讨论】:

  • codereview.stackexchange.com 会不会更好?
  • 哦,我什至不知道它的存在...感谢您告诉我!
  • 你不能仅仅因为每个单词不同就假设不会有冲突。您的哈希函数可以为多个不同的输入产生相同的输出。
  • 另外,如果你假设没有冲突,那么你为什么要使用带有 next 指针的节点结构呢?如果不考虑冲突,您可以只使用 char* 数组
  • 所以这都是实现 LRU 缓存的大型项目的一部分......基本上,我们得到一个 .txt 文件作为输入,我们需要对文件进行标记,并使用搜索文件比 O(n^2) 时间更好的东西(所以基本上,线性搜索是不可能的,我们鼓励使用哈希表)。 LRU 缓存是包含令牌的,并且是动态的:也就是说,用户指定自己的缓存大小。

标签: c pointers hash struct


【解决方案1】:

我没有详细阅读代码,但最明显突出的第一件事是哈希表大小,100。最好使用prime number for the size of your hash tables 来帮助避免冲突。

【讨论】:

  • 这是一个出现在多个地方的神奇数字。
  • @FredLarson:难怪它这么快就脱颖而出了 :) -- gfppaste,绝对用变量或#define 替换硬编码的100,这样您就可以更轻松地更改表格的大小未来。
  • 我不认为素数在这种情况下表现得更好。给定足够的散布(K&R 散列在镇上不是最好的,但可以用于合理长度的字符串),模 100 的性能不会比模 101 差很多
  • 鉴于显然没有输入冲突的可能性,无论如何这并不重要。 :)
【解决方案2】:

你似乎对分号有问题:

struct node_
{
    char * word;
    struct node * next;
}   /* <<-- HERE */
typedef struct node_ * node;

但是::

int hashFunction(char *word, int hashTableSize)
{
    int length = strlen(word);
    int h = 0;
    int i;  
    for(i = 0; i<length; i++)
    {
        h=31 *h  + word[i];
    }
    return h % hashTableSize;
}; /* <<-- NOT here */

此外,恕我直言,一个明智的建议是尽可能多地使用 unsigned 类型:用于哈希值(对负操作数进行模除做什么?)以及大小和索引。

经验法则:如果不能为负:则为无符号

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-09-28
    • 1970-01-01
    • 2017-06-17
    • 2013-04-15
    • 1970-01-01
    • 2019-05-25
    • 2016-09-16
    • 2015-01-05
    相关资源
    最近更新 更多