BKDRhash
unsigned int BKDRHash(char*str)
{
unsigned int seed=131 ;// 31 131 1313 13131 131313 etc..
unsigned int hash=0 ;
while(*str)
{
hash=hash*seed+(*str++);
}
return(hash % M); //M为存储空间的大小
}
(代码转 )
题目:http://poj.org/problem?id=2503
#include<stdio.h>
#include<string.h>
#define N 100003
#define Mod 100003
struct node
{
char english[20],foreign[20];
int next;
}word[N];
int first[N];
int m;
int ELFHash(char* key)
{
unsigned long g,h=0;
while(*key)
{
h=(h<<4)+*key++;
g=h & 0xf0000000L;
if(g) h^=g>>24;
h&=~g;
}
return h%Mod;
}
void insert(char english[],char foreign[])
{
strcpy(word[m].english,english);
strcpy(word[m].foreign,foreign); //一般要注意初始条件:first或叫pre都要赋为-1,而edge(边)中不必先赋为-1,因为edge会从first中赋值,
//如果只有一条那么自然edge1.next=-1,有两条则后面出现的一条指向前一条(。next的值为前一条边的编号)
//这里的m应当设为全局变量,且赋初值为1
int h=ELFHash(foreign);
word[m].next=first[h];
first[h]=m++;
}
/*讲一下这里的邻接表: 题目的要求是给出foregin 要求输出english
那么,理所当然的做法是找从foregin出发的边。
但是因为用了hash,所以多个foregin对应1个hash值,
正确的做法应该是从foergin对应的hash值列表中(就是从1个hash值出发的所有边中)去寻找,直到找到
(边符合信息)所求的foreign的。
(有所求foregin的边)
*/
int find(char foreign[])
{
int h=ELFHash(foreign);
for(int i=first[h];i!=-1;i=word[i].next)
{
if(strcmp(word[i].foreign,foreign)==0) return i;
}
return -1;
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
char str[100];
m=0;
memset(first,-1,sizeof(first));
while(gets(str))
{
if(str[0]==0) break;
char a[20],b[20];
sscanf(str,"%s %s",a,b);
insert(a,b);
}
while(scanf("%s",str)!=EOF)
{
int ans=find(str);
if(ans>=0) printf("%s/n",word[ans].english);
else printf("eh/n");
}
return 0;
}