您可以使用蛮力搜索按如下方式构建完美哈希。对于 64 个条目,目标数组的大小需要至少为 512 个条目,否则搜索将无法在合理的时间内找到索引。
完美的哈希函数是murmur(x + perfectHashIndex) & (TARGET_SIZE - 1)
#include <stdio.h>
#include <stdint.h>
#include <string.h>
static uint64_t murmur64(uint64_t h) {
h ^= h >> 33;
h *= UINT64_C(0xff51afd7ed558ccd);
h ^= h >> 33;
h *= UINT64_C(0xc4ceb9fe1a85ec53);
h ^= h >> 33;
return h;
}
// must be a power of 2
#define TARGET_SIZE 512
static uint64_t findPerfectHashIndex(uint64_t *array, int size) {
uint64_t used[TARGET_SIZE / 64];
for (uint64_t index = 0; index < 1000;) {
memset(used, 0, TARGET_SIZE / 64 * sizeof(uint64_t));
for (size_t i = 0; i < size; i++) {
uint64_t x = murmur64(array[i] + index) & (TARGET_SIZE - 1);
if (((used[x >> 6] >> (x & 63)) & 1) != 0) {
goto outer;
}
used[x >> 6] |= 1UL << (x & 63);
}
return index;
outer:
index++;
}
// not found
return -1;
}
int main() {
int size = 64;
uint64_t ids[size];
for(int i=0; i<size; i++) ids[i] = 10 * i;
uint64_t perfectHashIndex = findPerfectHashIndex(ids, size);
if (perfectHashIndex == -1) {
printf("perfectHashIndex not found\n");
} else {
printf("perfectHashIndex = %lld\n", perfectHashIndex);
for(int i=0; i<size; i++) {
printf(" x[%d] = %lld, murmur(x + perfectHashIndex) & (TARGET_SIZE - 1) = %d\n",
i, ids[i], murmur64(ids[i] + perfectHashIndex) & (TARGET_SIZE - 1));
}
}
}