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