哈希函数--字符串哈希--hdu1800 Flying to the Mars

本文介绍了一种基于ELFHash算法的字符串哈希方法,并详细解释了其在处理字符串冲突时的实现细节。通过对字符串进行位运算处理,该哈希算法能够确保不同字符串映射到不同的哈希值上,从而提高哈希表的查找效率。

#include <iostream>

#include <cstdio>

#include <cstring>

#include <algorithm>

using namespacestd;

const int N =7003;

//1.3000条记录,下列hash函数的效率平均为0.67-0.693000 7003 = 0.43, hash值数组开得稍大比较合适

//2.7003看起来像素数,适合取余

int cnt[N],hashnum[N];

int n,ans = 0;

//通过位运算,使每一位对hash值都产生影响,分布比较平均

//对长字符串和短字符串都有效。

int ELFhash (char *key )//452ms可能运算较复杂//ELFHash(Exextable and Linking Format ,ELF,可执行链接格式)函数

{

    unsignedlong h=0,g;

   while (*key)

    {

        h=(h<<4)+ *key;

        key++;

        g=h & 0xF0000000L;

       if (g) h^=g>>24;

        h &= ~g;

     }

    return h;

}

//unsigned int JSHash(char *str)//436ms

//{

//    unsigned int hash = 1315423911; // nearly a prime - 1315423911 = 3 * 438474637

//    while (*str)

//    {

//        hash ^= ((hash << 5) + (*str++) + (hash >> 2));

//    }

//    return (hash & 0x7FFFFFFF);

//}


//unsigned int SDBMHash(char *str)//436ms

//{

//    unsigned int hash = 0;

//    while (*str)

//    {

//        // equivalent to: hash = 65599*hash + (*str++);

//        hash = (*str++) + (hash << 6) + (hash << 16) - hash;

//    }

//    return (hash & 0x7FFFFFFF);//去掉标志位

//}

char str[N][35];

void hashstr(char *s)

{

    while (*s =='0') s++;

    unsignedint h = ELFhash(s),pos = h %N;

    while (hashnum[pos] != h &&hashnum[pos] != -1) pos = (pos +10) % N;//解决冲突

    if(hashnum[pos] == -1){

        hashnum[pos] = h;

    }

    cnt[pos] ++;

    ans =max(cnt[pos],ans);

    

}

int main()

{

    while (scanf("%d",&n) != EOF) {

        memset(hashnum, -1,sizeof(hashnum));

        memset(cnt,0, sizeof(cnt));

        ans =0;

        for (int i =0; i < n; i ++) {

            scanf("%s",str[i]);

            hashstr(str[i]);

        }

        printf("%d\n",ans);

    }

    return0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值