哈希代码的C递归

哈希代码的C递归,c,recursion,hash,C,Recursion,Hash,我想做一个hashcode函数 但是,我得到了一个不等于示例的随机数,我无法确定原因(5是最大长度,因此不需要动态内存分配)来自strncpy: 如果出现以下情况,则不会在目标的末尾隐式追加空字符: 源大于num。因此,在这种情况下,目标不应 被视为以null结尾的C字符串(这样读取会 溢出) 所以你想做: strncpy(new, str, l - 1); new[l - 1] = 0; 但您也可以避免使用助手函数创建新字符串: unsigned long hash_helper(const

我想做一个hashcode函数


但是,我得到了一个不等于示例的随机数,我无法确定原因(5是最大长度,因此不需要动态内存分配)

来自
strncpy

如果出现以下情况,则不会在目标的末尾隐式追加空字符: 源大于num。因此,在这种情况下,目标不应 被视为以null结尾的C字符串(这样读取会 溢出)

所以你想做:

strncpy(new, str, l - 1);
new[l - 1] = 0;
但您也可以避免使用助手函数创建新字符串:

unsigned long hash_helper(const char* str, int len){
    if (len == 0) return 0;
    return hash_helper(str, len - 1) * 65599 + str[len - 1]; 
}

unsigned long hash(const char* str){
    return hash_helper(str, strlen(str));
}

我忍不住觉得递归是一种奇怪的编码方式(在C-in-LISP中,它会很好)。在这段代码中,
hash1()
是哈希函数的简单迭代版本
hash2()
遵循递归规范,使用
hash3()
作为辅助函数(它需要长度):

请注意,
ice
的代码与示例匹配。当编译为32位程序时,输出为:

h1 = 873952427, h2 = 873952427: PASS (ice)
h1 = 906867258, h2 = 906867258: PASS (man)
h1 = 138275064, h2 = 138275064: PASS (cometh)
h1 = 1819095642, h2 = 1819095642: PASS (the iceman cometh)
== PASS ==

仅供参考,无论长度是否为5,都不需要动态分配。递归转发函数的设置将对任意长度执行此操作,并且不需要字符串分配或复制。你为什么决定在这里使用递归?你最好使用一个简单的循环。@Stilescris不确定你是在问我还是OP,但如果是我,因为这显然是OP任务的一个要求(我只假设这是一个学术练习)。如果是我(显然是你)的话,一个简单的循环将是当今的主流。@Dad你确定你是在一台64位无符号长的机器上编译的吗?我问是因为。。好。显然,它有32位的无符号长码,而同样的代码使用64位实现。如果您得到的是前者而不是后者,也许可以检查您的编译器目标。@爸爸,如果您的
long
s不够宽,请尝试
uint64\u t
unsigned long
。该方法需要适合指定的原型,这样我就无法将其更改为long-long,我不知道该怎么做do@Dad,如果unsigned long无法在您的体系结构上存储所需的结果,那么只有一个选项:假设采用64位体系结构。
h1 = 451845518507, h2 = 451845518507: PASS (ice)
h1 = 469058302522, h2 = 469058302522: PASS (man)
h1 = 8177059914254772472, h2 = 8177059914254772472: PASS (cometh)
h1 = 2988038870251942490, h2 = 2988038870251942490: PASS (the iceman cometh)
== PASS ==
h1 = 873952427, h2 = 873952427: PASS (ice)
h1 = 906867258, h2 = 906867258: PASS (man)
h1 = 138275064, h2 = 138275064: PASS (cometh)
h1 = 1819095642, h2 = 1819095642: PASS (the iceman cometh)
== PASS ==