高效的哈希函数wrt。字符串连接?

时间:2014-06-20 17:45:32

标签: c string performance data-structures hash

我正在用玩具语言试验一些数据结构,因为我做了大量的文本处理,所以我希望字符串操作能够快速完成。我将字符串存储为具有缓存长度和哈希值的不可变绳索。目标是仅在实例化绳索的叶子节点时执行散列函数。是否有任何现有的哈希函数可以做到这一点?

我的绳索结构如下:

#define HASHLEN 128
#define HASHMUL 2
typedef unsigned long hashtype;
typedef struct rope rope;

// K&R2 hash function
hashtype hash(const char *s) {
    hashtype h = 0;
    while (*s != '\0') {
        h = h * HASHMUL + *s++;
    }
    return h; // won't be modded until the actual table access is performed
}

struct rope {
    unsigned weight;
    hashtype hash;
    rope *left;  // if NULL, indicates that r->right is a char *
    void *right; // if r->left is non-NULL, r->right is a rope *
};

和连接函数如下所示:

// integer exponentiation--by squaring
hashtype iexp(hashtype k, unsigned n);

rope *newrope(const char *s) {
    rope *r = (rope *) malloc(sizeof(rope));
    r->weight = strlen(s);
    r->hash = hash(s);
    r->left = NULL;
    r->right = (void *) s;

    return r;
}

rope *ropecat(rope *left, rope *right) {
    rope *r = (rope *) malloc(sizeof(rope));
    r->weight = left->weight + right->weight;
    r->hash = left->hash * iexp(HASHMUL, right->weight) + right->hash;
    r->left = left;
    r->right = (void *) right;

    return r;
}

较大的素数对于HASHMUL会更好(K&amp; R2使用31,我听说33是“最好的”),但是我担心哈希函数的快速增长长字符串,它可能会绕过ULONG_MAX并打破哈希机制,所以我选择了一个可能更顺畅地包裹的数字。同时将HASHMUL设置为2可以将left->hash * iexp(HASHMUL->hash, right->weight)重写为left->hash << right->weight,将HASHLEN设置为128或其他二进制数可让我使用r->hash & (HASHLEN-1)代替{{1} }}

这就是我要做的事情的概要。我正在寻找一种快速,在恒定时间内分配的散列函数,并且具有合理的分布。天真的K&amp; R2散列函数在这里是否正常工作,或者我应该使用不同的r->hash % HASHLEN,还是应该完全寻找另一个散列函数?

0 个答案:

没有答案