zoukankan      html  css  js  c++  java
  • 动物统计 (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; 
       } 
         
    }
    
  • 相关阅读:
    一套完整的测试应该由哪些阶段组成?
    测试结束的标准是什么?
    :你的测试职业发展目标是什么?
    您认为做好测试用例设计工作的关键是什么?
    Servlet API中forward()与redirect()的区别?
    AOP 核心概念?
    Spring 中使用了哪些设计模式?
    ArrayList类?
    如何实现拦截器?
    什么是集合?
  • 原文地址:https://www.cnblogs.com/HpuAcmer/p/2281348.html
Copyright © 2011-2022 走看看