哈夫曼译码器

来源:互联网 发布:知乎 mac怎么上google 编辑:程序博客网 时间:2024/05/29 15:38
#include<stdio.h>#include<math.h>#include<string.h>#include<stdlib.h>#define N 27#define TYPE inttypedef struct {  TYPE w;  int f,l,r;}HNode,*Htree;typedef struct{  char c;  char code[10];}Hcode, *Huffman;void creat_HuffmanTree(HNode HT[],char ch[],int n1 )//n1为树节点数{  int i,j;  TYPE low1,low2;  int p1=0,p2=0;        //初始化p1,p2  for ( i=N+1; i<=n1; i++ )  {    low1=999,low2=999;    for ( j=1;j<i;j++)    {            if ( HT[j].f==0 && HT[j].w<low1)      {        low1=HT[j].w;        p1=j;      }        }    for ( j=1;j<i;j++)      if ( HT[j].f==0 && HT[j].w<low2 &&  j!=p1 )      {        low2=HT[j].w;        p2=j;      }           HT[p1].f=i;       HT[p2].f=i;        HT[i].l=p1;        HT[i].r=p2;        HT[i].w=low1+low2;   }}void creat_Huffmancoding( HNode HT[],Hcode HC[],char ch[],int n1,int n2)//n1为树节点数,n2为符号个数{             //左1右0  int i,j,m,ff;  char tmp[20];  for ( i=1;i<=n2;i++ )  {    ff=i;    j=0;        while ( HT[ff].f!=0 )    {           if ( HT[ HT[ff].f ].l==ff)        tmp[j++]='1';      else tmp[j++]='0';      ff=HT[ff].f;    }    tmp[j]='\0';    HC[i].c =ch[i];      //字符下标从1开始    for ( m=0;m<j;m++ )      HC[i].code[m]=tmp[j-1-m];    HC[i].code[m]='\0';  }}void ECode(Hcode HC[]){  int i=0,j;  char ss[100];  gets(ss);  while ( i<(int)strlen(ss) )  {    for ( j=1;j<=N;j++ )  //N为HC下标     if (HC[j].c==ss[i])     {      printf ("%s ",HC[j].code);      break;     }     if (j>N)      printf ("ERROR ");    i++;  }  printf ("\n");  }void DCode(Hcode HC[N+1]){  char ss[100];  int i,j,m,k[N+1]={0},maxlen=0,tmp[N+1][N+1]={0};//tmp   几位字符,存放地址  int begin,l,flag;  char st[N+1];  for ( i=1;i<=N;i++ )  {    j=strlen(HC[i].code);    tmp[j][k[j]++]=i;    if (j>maxlen)     maxlen=j;  }  gets(ss);  for ( begin=0;begin<(int)strlen(ss);)  {     for ( flag=l=0,j=begin;j<begin+maxlen;j++,l++ )     {     st[l]=ss[j];     st[l+1]='\0';       for ( m=0;m<k[j-begin+1];m++ )     if (memcmp(st,HC[tmp[j-begin+1][m]].code,strlen(st) )==0)     {       printf ("%c",HC[tmp[j-begin+1][m]].c);       flag=1;       break;     }     if (flag==1){          begin+=l+1;          break;        }     }    if (flag==1) flag=0;     else printf("ERROE ");  }  printf ("\n");}int main(){  int i,k;  char ch[N+1]={'0','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',' '};  TYPE n[N]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27};         //默认权值  HNode HT[2*N];  Hcode HC[N+1];        for ( i=1;i<=N;i++ )  {    HT[i].w=n[i-1];       }  for ( i=1;i<=2*N;i++)      //结构体数据f,l,r,w初始化   HT[i].f=HT[i].l =HT[i].r =0;  creat_HuffmanTree (HT,ch,2*N-1);  creat_Huffmancoding (HT,HC,ch,2*N-1,N);  printf ("________________最短编码__________________________________________\n");  printf ("_____1· 26个小写字母和空格进行赫夫曼编码_____________________________\n");  printf ("_____2· 输入一个英文句子,输出其编码    _______________________________\n");  printf ("_____3· 输入一个01序列,输出原文        ________________________________\n");  printf ("_________________________________________________________________\n");        printf ("输入序列号:");  while(scanf ("%d",&k)&&  k!=0)  { getchar();   switch (k)   {   case 1:for ( i=1;i<=N;i++)       {      printf ("%c  %8s\t",HC[i].c,HC[i].code);      if (!i%5)printf ("\n");       }printf ("\n");     break;   case 2:ECode(HC);break;   case 3:DCode(HC);break;   default:        break;       }  }    return 0;}

0 0