zoj1117 Entropy

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1117

典型的霍夫曼编码题目,题目就是让你根据所给的字符串设计霍夫曼编码,然后输出总的编码后长度。如果你以前写过霍夫曼编码的代码,那么直接在这里用就好了,如果对霍夫曼编码不了解的话,参照:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1117 (此处失误,链接贴错了,算了,诸位自己Google吧)里面讲的非常清楚,我也是照这里写的。代码如下:

#include<stdio.h> #include<string.h> #define MAXLEAFNUM 50 struct node{ char ch; int weight; int parent; int deep; int lchild,rchild; }HT[2*MAXLEAFNUM]; void select(int n,int& s1,int& s2) { int min1,min2; min1 = min2 = 0; HT[0].weight = 30000; for(int i=1;i<=n;i++) { if(HT[i].parent!=0) continue; if(HT[i].weight < HT[min1].weight) min1 = i; } for(int i=1;i<=n;i++) { if(HT[i].parent!=0||i==min1) continue; if(HT[i].weight <HT[min2].weight) min2 = i; } s1 = min1; s2 = min2; } void createHTree(char* c, int* w, int n) { if(n<=1) return; int i; for(i=1;i<=n;i++) { HT[i].ch = c[i-1]; HT[i].weight = w[i-1]; HT[i].parent= HT[i].lchild = HT[i].rchild = 0; } for(;i<2*n;++i) { HT[i].parent = HT[i].lchild = HT[i].rchild = 0; } //构造霍夫曼树 for(i=n+1;i<2*n;i++) { int s1,s2; select(i-1,s1,s2); HT[s1].parent = i; HT[s2].parent = i; HT[i].lchild = s1; HT[i].rchild = s2; HT[i].weight = HT[s1].weight + HT[s2].weight; } } void setDeep(int num) { HT[HT[num].lchild].deep = HT[num].deep+1; HT[HT[num].rchild].deep = HT[num].deep+1; if(HT[num].rchild!=0) setDeep(HT[num].rchild); if(HT[num].lchild!=0) setDeep(HT[num].lchild); } void getLen(int n) { int p = 2*n-1; HT[p].deep = 0; setDeep(p); } int main() { char sen[1000]; char c[100]; int w[100]; int l[100]; int charnum; scanf("%s",&sen); while(strcmp(sen,"END")!=0) { charnum = 0; int len = strlen(sen); printf("%d ",len*8); for(int i=0;i<len;i++) { bool flag = false; int j; for(j=0;j<charnum;j++) { if(c[j]==sen[i]) { flag = true; break; } } if(!flag) { c[charnum] = sen[i]; w[charnum] = 1; l[charnum] = 0; charnum++; }else { w[j]++; } } createHTree(c,w,charnum); getLen(charnum); int ans = 0; if(charnum==1) { ans = len; }else { for(int i=1;i<=charnum;i++) ans += HT[i].deep*HT[i].weight; } printf("%d %.1f/n",ans,(double)8*len/ans); scanf("%s",&sen); } }

你可能感兴趣的:(c,struct,Google)