Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 802 Accepted Submission(s): 299
这是作者第一次写赫夫曼,虽然WRONG了几次,但是最终把它做出来了,也算是一种小小的成就吧。本题的思想就是根据所给的字符串判断每个字符的权重,然后再根据每个字符的权重来构建赫夫曼树,最后对赫夫曼树遍历,判断每个字符所在的层数,所有字符的层数*个数就等于压缩后的大小:
赫夫曼的构建思想是:将所有的节点放入到优先队列里面,对优先队列进行重载,是从小到大排列。每次取出优先队列前两个数。组成一个数之后再放进优先队列。依次循环下去,直到只剩下一个的时候便是根节点。
代码:
1 #include<stdio.h>
2 #include<queue>
3 #include<string.h>
4 using namespace std;
5 int k[1000];
6 typedef struct T
7 {
8 char data; // 记录字符
9 bool o; // 记录是字符还是由字符重组的
10 struct T *Lchild,*Rchild;
11 }*Tree;
12 typedef struct node
13 {
14 int n; // 记录每个字符的权重
15 int h; // 记录是字符还是由字符重组的
16 Tree t;
17 bool operator<(const node &a)const
18 { //对优先队列进行重载,权重从小到大如果权重相同,重组的让给单个
19 if(a.n!=n)
20 return a.n<n;
21 else
22 return a.h<h;
23 }
24 }NODE;
25
26 NODE cur1,cur2,cur;
27 priority_queue<NODE> qu;
28 void createTree()
29 {
30 cur1=qu.top();
31 qu.pop();
32 if(qu.empty())
33 return ;
34 cur2=qu.top();
35 qu.pop();
36 cur.n = cur1.n + cur2.n;
37 cur.h=1;
38 cur.t=(Tree)malloc(sizeof(T));
39 cur.t->Lchild=cur1.t;
40 cur.t->Rchild=cur2.t;
41 cur.t->data=' ';
42 cur.t->o=false;
43 qu.push(cur);
44 createTree();
45 }
46 void visit(Tree c,int floor)
47 {
48 if(c->o==true)
49 {
50 if(c->data=='_')
51 k[0]=floor;
52 else
53 k[c->data-'A'+1]=floor;
54 }
55 if(c->Lchild !=NULL)
56 visit(c->Lchild,floor+1);
57 if(c->Rchild !=NULL)
58 visit(c->Rchild,floor+1);
59 }
60 int main()
61 {
62 char a[1000];
63 int i,j,mark[1000],len,count,sum;
64 while(scanf("%s",a)!=EOF)
65 {
66 sum=0;
67 while(!qu.empty())
68 qu.pop();
69 memset(mark,0,sizeof(mark));
70 memset(k,0,sizeof(k));
71 if(strcmp(a,"END")==0)
72 break;
73 len=strlen(a);
74 for(i=0;i<len;i++)
75 {
76 count=0;
77 if(!mark[i])
78 {
79 for(j=i;j<len;j++)
80 {
81 if(a[i]==a[j])
82 {
83 mark[j]=1;
84 count++;
85 }
86 }
87 cur1.n=count;
88 cur1.h=0;
89 cur1.t=(Tree)malloc(sizeof(T));
90 cur1.t->data=a[i];
91 cur1.t->Lchild =NULL;
92 cur1.t->Rchild =NULL;
93 cur1.t->o=true;
94 qu.push(cur1);
95 }
96 }
97 if(qu.size()==1)
98 {
99 printf("%d %d 8.0\n",len*8,len);
100 continue;
101 }
102 createTree();
103 visit(cur1.t,0);
104 for(i=0;i<len;i++)
105 if(a[i]=='_')
106 sum+=k[0];
107 else
108 sum+=k[a[i]-'A'+1];
109 printf("%d %d %.1lf\n",len*8,sum,len*8*1.0/sum);
110 }
111 return 0;
112 }
113
114
115