C smdb哈希值%tableSize重复评估相同的值? (输入不同。)

时间:2017-04-11 17:11:12

标签: c hash linked-list

尝试使用smdb算法制作哈希表(因为我听说不尝试自己编写哈希表是明智的。)我确信我做错了。我提到我是C的新手吗?

我的hashFunction()%size首次在第一次调用时返回35之类的数字,然后在第二次调用,第三次调用,第四次调用...时返回65无限广告。我只是将这些数字用作任意例子。在尝试使用调试器解决问题之后,我注意到hashFunction返回了不同的long,但它们都以相同的最后2个数字结束......就像这样......

  

4460735 4526335 4591935

所以我想这就是为什么当我散列%size时,我每次都得到相同的输出。这违背了均匀分布的密钥的想法,对吗?

请放轻松。我知道SO上的野蛮人是多么可以。

#include <stdio.h>
#include <stdlib.h>

typedef struct node
{
    char* str;
    struct node* next;
} 
node;

void insertItem(char* number, node** list);
unsigned long hashFunction(char* str);

int main(void)
{

    int size = 100;
    int index = 0;

    node* buckets[size];

    for (int i = 0; i < size; i++)
    {
        char c = i + 'A';
        index = hashFunction(&c) % size;
        insertItem(&c, &buckets[index]);
    }

}

void insertItem(char* str, node** list)
{
    node* newItem = malloc(sizeof(node));
    newItem->str = str;
    newItem->next = *list;
    *list = newItem;
}

unsigned long hashFunction(char* str)
{
    //sdbm hash function adapted (incorrectly?) from here: http://www.cse.yorku.ca/~oz/hash.html
    unsigned long hash = 0;
    int c;

    while ((c = *str++))
        hash = c + (hash << 6) + (hash << 16) - hash;

    return hash;
}

2 个答案:

答案 0 :(得分:2)

问题是你对不在字符串上的字符进行测试。

如果您使用真实字符串提供算法,那么您将获得更重要的信息。例如,使用以下代码更改代码:

char mystring[] = "Any string will do !";

for (int i = 0; i < size; i++)
{
    mystring[0] = i; // simple hack to change the string a bit, well ... a byte ;)
    index = hashFunction(mystring) % size;
    insertItem(mystring, &buckets[index]);
}

如果您打印index,您将获得更合适的索引。

编辑:

真正的问题是你的哈希函数被设计为获得一个C字符串作为参数(一个指向缓冲区的char *必须以空终止,即以'\0'结尾)。当您给出单个字符的地址时,第一个取消引用是可以的,但是使用指向不是真正分配对象的下一个地址(在++之后)是undefined behavior。 / p>

致谢:请参阅moooeeeep answer和评论。

答案 1 :(得分:2)

散列函数需要一个指向空终止字符串的指针作为输入参数。您将指针传递给单个字符。然后,该函数迭代无效内存,直到它到达一个随机空字节。

char arr[] = "Hello World";
index = hashFunction(arr) % size;

您需要将指针传递给字符串。例如:

size

还可以考虑将def springSecurityService 设置为素数以增加随机性。进一步阅读: