彭小路
My life is brilliant~

导航

 

今天在做HDOJ上的1800 题,题目描述的很复杂,其实解题思路归纳起来就这么一句话:

  “给你一系列数字,找出出现次数最多的那个”

由于测试样本给的数字可能很大,范围超出__int64的表示范围,所以只能用个字符串来写大数了

用的是C语言,也只能自己写hash算法。

由于是多组测试数据,所以每次都要把hash表清空,开始随手写了个

1 for(i=0;i<NHASH;i++)
2       carr[i] = NULL;

代码提交后,不管怎么样,AC了,不过内存使用虽然在AC范围内,但也出奇的大。

想了半天,是上面代码的问题,因为数组里面每个元素都可能是长度大于一的链表,结构如下:

1 typedef struct MyCount MyCount;
2 struct MyCount {
3     char num[32];
4     int cnt;
5     MyCount *next;
6 };

所以很显然,我几乎没有正确的free已经分配出去的内存

而free链表的话,很容易就会引起内存泄露,正确的free链表的代码如下(来自《Expert C Programming》):

1 struct node *p, *start, *tmp;
2 for(p=start; p; p=tmp){
3     tmp = p->next;
4     free(p);
5 }

另附上AC代码,AC的效率不高,但是也算是可作为参考用C实现了一个简单的hash表

View Code
 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <string.h>
 4 #define MULTIPLIER 31
 5 #define NHASH 1023
 6 typedef struct MyCount MyCount;
 7 struct MyCount {
 8     char num[32];
 9     int cnt;
10     MyCount *next;
11 };
12 MyCount *carr[NHASH];
13 int hash(char *str) {
14     unsigned int h;
15     unsigned char *p;
16     h=0;
17     for(p=(unsigned char *)str; *p!='\0'; p++)
18         h = MULTIPLIER * h + *p;
19     return h%NHASH;
20 }
21 void add(char *str) {
22     int h;
23     int findit = 0;
24     MyCount *sp;
25     h = hash(str);
26     for(sp = carr[h]; sp!=NULL; sp = sp->next) {
27         if(strcmp(str,sp->num) == 0){//find it
28             sp->cnt++;
29             findit = 1;
30             break;
31         }
32     }
33     if(findit==0){//did not find it
34         sp = (MyCount *)malloc(sizeof(MyCount));
35         strcpy(sp->num,str);
36         sp->cnt = 1;
37         sp->next = carr[h];
38         carr[h] = sp;
39     }
40 }
41 
42 
43 int main() {
44     int n;
45     char temp[32];
46     char *p;
47     int i,max;
48     MyCount *sp;
49     while(scanf("%d",&n)!=EOF) {
50         for(i=0;i<NHASH;i++)
51             carr[i] = NULL;
52         max = 0;
53         while(n--) {
54             scanf("%s",temp);
55             p = temp;
56             while(*p=='0')
57                 p++;
58             add(p);
59         }
60         for(i=0;i<NHASH;i++){
61             sp = carr[i];
62             while(sp){
63                 if(sp->cnt>max)
64                     max = sp->cnt;
65                 //printf("##%s %d\n",sp->num,sp->cnt);
66                 sp = sp->next;
67             }
68         }
69         printf("%d\n",max);
70     }
71     return 0;
72 }

 

  

posted on 2012-11-05 19:54  彭小路  阅读(853)  评论(0编辑  收藏  举报