动物统计 (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; 
   } 
     
}

 

posted @ 2011-12-08 22:38  开开甲  阅读(406)  评论(0编辑  收藏  举报