poj3274 hash

怎么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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值