不要散列数组的元素,而是散列两个相邻单元格的差异:
#include <stdio.h>
unsigned hashdiff(unsigned arr[], size_t siz);
/* toy hash function: don't try this at home ... */
#define HASH1(v) ((v)*7654321)
unsigned hashdiff(unsigned arr[], size_t siz)
{
unsigned idx;
unsigned hash;
if (siz < 1) return 0;
if (siz < 2) return HASH1(arr[0]);
hash = HASH1( arr[0] - arr[siz-1] );
for(idx=1; idx < siz; idx++) {
hash ^= HASH1(arr[idx] - arr[idx-1] );
}
return hash;
}
unsigned arr1[] = {1,9,8,7};
unsigned arr2[] = {9,8,7,1 };
unsigned arr3[] = {1,8,9,7 };
unsigned arr4[] = {1,9,8,5 };
int main(void)
{
unsigned hash;
hash = hashdiff (arr1, 4); printf("%x\n", hash);
hash = hashdiff (arr2, 4); printf("%x\n", hash);
hash = hashdiff (arr3, 4); printf("%x\n", hash);
hash = hashdiff (arr4, 4); printf("%x\n", hash);
return 0;
}
结果:
./a.out
fee56452
fee56452
1100b22
fca02416
更新:如果您不希望 {1,2,3,4} 和 {11,12,13,14} 散列到相同的值,您可以像这样扩大差异:
#define HASH1(v) ((v)*7654321)
#define HASH2(a,b) HASH1(3u*(a)-5u*(b))
unsigned hashdiff2(unsigned arr[], size_t siz)
{
unsigned idx;
unsigned hash;
if (siz < 1) return 0;
if (siz < 2) return HASH1(arr[0]);
hash = HASH2( arr[0] , arr[siz-1] );
for(idx=1; idx < siz; idx++) {
hash ^= HASH2( arr[idx] , arr[idx-1] );
}
return hash;
}