Hnust 1071 赫夫曼编码

来源:互联网 发布:java log4j 编辑:程序博客网 时间:2024/04/28 05:12

问题 J: 赫夫曼编码

时间限制: 1 Sec  内存限制: 128 MB
提交: 15  解决: 6
[提交][状态][讨论版]

题目描述

赫夫曼编码能够产生最短的报文。以报文“ABCDABCDABCABDABAA”为例,A编为0,B对应10,C对应110,D对应111,整体的报文长度为35位二进制。相比于定长的ASCII码,压缩比达到了18*8/35=4.1。

输入

输入有一系列的字符串组成,每个字符串占据一行。字符串仅包含大写字母和下划线。字符串“END” 表示处理结束,不应对其处理。

输出

对每一个字符串,输出其ASCII编码的比特位长度,赫夫曼编码的比特位长度,以及二者之比,精确到小数点后一位。

样例输入

ABCDABCDABCABDABAA
AAAAAAAAAAAAAAAAAA
END

样例输出

144 35 4.11
44 18 8.0
 
#include<stdio.h> #include<stdlib.h> #include<string.h>   struct Node{     int v;     int hash;     int a;     int parent; }num[200];   int fcmp(const void *a,const void *b) {     return ((struct Node *)a)->v-((struct Node *)b)->v; }   int fcmp2(const void *a,const void *b) {     return ((struct Node *)a)->a-((struct Node *)b)->a; } char c[1000001];   int main(void) {     int count,i,d1,d2,ok;     while(scanf("%s",c))     {         if(strcmp(c,"END")==0)             break;         d1=strlen(c)*8;         count=0;         for(i=0;i<200;i++)         {             num[i].v=0;             num[i].hash=0;             num[i].parent=-1;             num[i].a=i;         }         for(i=0;c[i];i++)         {             if(c[i]!='_')             {                 num[c[i]-'A'].v++;             }             else                num[26].v++;         }         int tmp1,tmp2,flag;         count=26;         ok=0;         while(1)         {             flag=0;             qsort(num,count+1,sizeof(num[0]),fcmp);             for(i=0;i<=count;i++)             {                 if(!num[i].hash && num[i].v!=0)                 {                     num[i].hash=1;                     tmp1=i;                     i++;                     break;                 }             }             while(i<=count)             {                 if(!num[i].hash && num[i].v!=0)                 {                     ok=1;                     num[i].hash=1;                     tmp2=i;                     i++;                     flag=1;                     break;                 }                 i++;             }             if(!flag)                 break;             num[tmp1].parent=count+1;             num[tmp2].parent=count+1;             count++;             num[count].parent=-1;             num[count].v=num[tmp1].v+num[tmp2].v;             num[count].a=count;         }         if(ok==0)         {             for(i=0;i<=26;i++)             {                 if(num[i].v)                     d2=num[i].v;             }         }         else        {             qsort(num,count+1,sizeof(num[0]),fcmp2);             num[count].parent=-1;             int len,tmp;             d2=0;             for(i=0;i<=26;i++)             {                 tmp=i;                 len=0;                 while(num[tmp].parent!=-1)                 {                     tmp=num[tmp].parent;                     len++;                 }                 d2+=len*num[i].v;             }         }         printf("%d %d %.1lf\n",d1,d2,(double)d1/(double)d2);     }     return 0; } /**************************************************************     Problem: 1071     Language: C++     Result: Accepted     Time:0 ms     Memory:1784 kb ****************************************************************/