描述
- 在美丽大兴安岭原始森林中存在数量繁多的物种,在勘察员带来的各种动物资料中有未统计数量的原始动物的名单。科学家想判断这片森林中哪种动物的数量最多,但是由于数据太过庞大,科学家终于忍受不了,想请聪明如你的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[N];
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;
}
}