您的位置:首页 > 其它

动物统计 (Hash)

2011-12-08 22:38 218 查看

描述

在美丽大兴安岭原始森林中存在数量繁多的物种,在勘察员带来的各种动物资料中有未统计数量的原始动物的名单。科学家想判断这片森林中哪种动物的数量最多,但是由于数据太过庞大,科学家终于忍受不了,想请聪明如你的ACMer来帮忙。

输入第一行输入动物名字的数量N(1<= N <= 4000000),接下来的N行输入N个字符串表示动物的名字(字符串的长度不超过10,字符串全为小写字母,并且只有一组测试数据)。输出输出这些动物中最多的动物的名字与数量,并用空格隔开(数据保证最多的动物不会出现两种以上)。样例输入
10
boar
pig
sheep
gazelle
sheep
sheep
alpaca
alpaca
marmot
mole

样例输出
sheep 3

数据量太大,用map显然会超时,用Hash可以过(还有其他方法,这里只谈Hash)。
首先得找个字符串Hash函数,听说BKDRHash非常高效,就拿来用了,至于原理希望路过的大牛指点。确实不知道!

然后用链地址法处理冲突就OK了,动态更新最大值。

我的代码:

#include<stdio.h>
#include<string.h>
#include<malloc.h>
#define N 4300000

typedef struct node
{
char ch[11];//存放动物名称
int cnt;//计数器
struct node *next;
} Animal;

Animal a
;
unsigned int BKDRHash(char *str);//一个很高效的字符串Hash函数
Animal * search(Animal an[],int n , char *str);
void insert(Animal an[],int n ,char *str);

int main()
{
Animal *temp;
int n,i,id,max;
char t[11];
scanf("%d",&n);
getchar();

max = 1;
for(i = 0 ; i < n ; ++i)
{
char c[11];
scanf("%s",c);
insert(a,N,c);
temp = search(a,N,c);
if(temp->cnt > max)
{
max = temp->cnt ;
strcpy(t,temp->ch);
}
}
printf("%s %d\n",t,max);

//system("pause");
return 0;
}

/* 这个函数是借用,我也看不太懂,希望懂的高手指点下 */
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 & 0x7FFFFFFF) % N;
}

Animal * search(Animal an[],int n , char *str)
{
Animal *p;
int pos;
pos = BKDRHash(str);
p = &an[pos];
while(p && strcmp(p->ch,str) )//查找
p = p->next;
return p;//如果为NULL,则表示没找到。
}

void insert(Animal an[],int n ,char *str)
{
Animal *p,*one;
int pos;
p = search(an,n,str);
if(p)
{
++(p->cnt);//找到了,计数器加 1
}
else//没找到,就插入
{
pos = BKDRHash(str);
one = (Animal *)malloc(sizeof(Animal));
strcpy(one->ch,str);
one->cnt = 1;//新来的,计数器置 1
one->next = an[pos].next;
an[pos].next = one;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: