怎么hash网上已经说得很清楚,我就不多说了。
我看的这个博客: http://hi.baidu.com/aconly/blog/item/9d1ed1122a29af876538db0b.html
直接贴一下我的代码, 也有一些我做的过程中遇到的问题:
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
#define K 33
#define N 100005
#define SIZE 200003
//tableSize 取满足4 * k + 3的质数,且闭散列使装载因子<=0.5,所以tableSize取总元素个数的2倍
int sum[N][K], a[N][K];
int hash[SIZE];
inline int hashcode(int v[], int k) //网上的hash函数,据说是折叠法
{
int val = 0;
for (int i = 1; i < k; i++)
val = ((val << 2) + (v[i] >> 4)) ^ (v[i] << 10);
val = val % SIZE;
val = val < 0 ? val + SIZE : val;
return val;
}
int main()
{
int n, k, id;
int i, j, r, ans = 0;
scanf("%d %d", &n, &k);
memset(sum[0], 0, sizeof(sum[0]));
memset(hash, -1, sizeof(hash));
memset(a[0], 0, sizeof(a[0]));//注意:
hash[hashcode(a[0], k)] = 0; // 下标从1开始,但是下标为0也必须加入散列表中,因为如果
// 1,2, 3,4是平衡的了,我们比较的是,a[4]和a[0](而不是a[1])是否对应相等。
for (i = 1; i <= n; i++) //下标从1开始
{
scanf ("%d", &id);
for (j = 0; j < k; j++) {
sum[i][j] = sum[i - 1][j] + (1 & (id >> j));
a[i][j] = sum[i][j] - sum[i][0];
}
int p = hashcode(a[i], k), m = 0;
while (hash[p] != -1)
{
for (r = 1; r < k; r++)
if (a[hash[p]][r] != a[i][r])
break;
if (r == k) {
if (ans < i - hash[p])
ans = i - hash[p];
break; //hash[p]的值是所有映射到p这个地址的a[i]数组中最小的i值,所以一旦找到就可直接跳出循环
}
p += 2 * (++m) - 1; //平方探测法
if (p >= SIZE) p -= SIZE;
}
if (hash[p] == -1) //如果没有搜索到,则将目前的插入到表中
hash[p] = i;
}
printf("%d\n", ans);
return 0;
}