编码器 译码器 源码实现
(1) 对26个小写字母和空格进行赫夫曼编码 ;
(自己假设字符的频率)
(2) 编码:输入一个英文句子,输出其编码;
(3) 译码:输入一个01序列,输出原文
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
#define N 27
#define TYPE int
typedef 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;
}