poj2503

poj2503题目意思很简单:就像查找一本字典,根据输入的条目和要查询的单词,给出查询结果(每个单词长度不超过10)。这题有很多实现方式,最容易想到的就是map,但这是acm训练且stl里面的map速度不够快,那就要另谋出路。

    数据量为100,000。可以想到的是快排+二分,复杂度是O(nlog2n)。还有就是哈希,哈希查询时间是O(1),当然,还要考虑哈希冲突,设计合理的字符串哈希函数。

    首先是快排+二分,比较简单。

Cpp代码  收藏代码
  1. #include <iostream>  
  2. const int MAX = 100001;  
  3. typedef struct  
  4. {  
  5.     char e[11];  
  6.     char f[11];  
  7. }Entry;  
  8. Entry entry[MAX];  
  9. int i = 0;      //词典总条数  
  10.   
  11. int cmp(const void *a, const void *b)  
  12. {  
  13.     return strcmp((*(Entry *)a).f, (*(Entry *)b).f);  
  14. }  
  15.   
  16. int BinSearch(char c[])  
  17. {  
  18.     int low = 0, high = i - 1;  
  19.     int mid, t;  
  20.     while(low <= high)  
  21.     {  
  22.         mid = (low + high) / 2;  
  23.         t = strcmp(entry[mid].f, c);  
  24.         if(t == 0)  
  25.             return mid;  
  26.         else if(t == -1)  
  27.             low = mid + 1;  
  28.         else  
  29.             high = mid - 1;  
  30.     }  
  31.     return -1;  
  32. }  
  33.   
  34. int main()  
  35. {  
  36.     char str[25];  
  37.     int index = -1;  
  38.     while(gets(str))  
  39.     {  
  40.         if(str[0] == '\0')  
  41.             break;  
  42.         sscanf(str,"%s%s",entry[i].e,entry[i].f);  
  43.         i++;  
  44.     }  
  45.     qsort(entry,i,sizeof(Entry),cmp);    
  46.     while(gets(str))  
  47.     {  
  48.         index = BinSearch(str);  
  49.         if(index == -1)  
  50.             printf("eh\n");  
  51.         else  
  52.             printf("%s\n",entry[index].e);  
  53.     }  
  54.     return 0;  
  55. }  

 

    对于字符串的哈希,在《算法艺术与信息学竞赛》推荐使用ELFHash函数。对于哈希冲突的处理,采用的是链表法(个人认为线性探测等效率不是很高)。

Cpp代码  收藏代码
  1. #include <iostream>  
  2.   
  3. const int M = 149993;  
  4.   
  5. typedef struct  
  6. {  
  7.     char e[11];  
  8.     char f[11];  
  9.     int next;  
  10. }Entry;  
  11. Entry entry[M];  
  12. int i = 1;      //词典总条数  
  13. int hashIndex[M];  
  14.   
  15. int ELFHash(char *key)  
  16. {  
  17.     unsigned long h=0;  
  18.     while(*key)  
  19.     {  
  20.         h=(h<<4)+(*key++);  
  21.         unsigned long g=h&0Xf0000000L;  
  22.         if(g) h^=g>>24;  
  23.         h&=~g;  
  24.     }  
  25.     return h%M;  
  26. }  
  27.   
  28. void find(char f[])  
  29. {  
  30.     int hash = ELFHash(f);  
  31.     for(int k = hashIndex[hash]; k; k = entry[k].next)  
  32.     {  
  33.         if(strcmp(f, entry[k].f) == 0)  
  34.         {  
  35.             printf("%s\n",entry[k].e);  
  36.             return;  
  37.         }  
  38.     }  
  39.     printf("eh\n");  
  40. }  
  41.   
  42. int main()  
  43. {  
  44.     char str[22];  
  45.     while(gets(str))  
  46.     {  
  47.         if(str[0] == '\0')  
  48.             break;  
  49.         sscanf(str,"%s %s",entry[i].e,entry[i].f);  
  50.         int hash = ELFHash(entry[i].f);  
  51.         entry[i].next = hashIndex[hash];  
  52.         hashIndex[hash] = i;  
  53.         i++;  
  54.     }  
  55.     while(gets(str))  
  56.         find(str);  
  57.     return 0;  
  58. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值