📄 huffman_32.cpp
字号:
// Huffman1.cpp : Defines the entry point for the console application.
//
#include "stdio.h"
#include "string.h"
#define N 256
int m,n;
long unsigned int len;
struct Node
{
char ch;
int weight,parent,lc,rc,data;
}HT[N];
void init()//初始化
{
int i;
for (i=0;i<N;i++)
{
HT[i].weight=0;
HT[i].parent=0;
HT[i].lc=-1;
HT[i].rc=-1;
}
}
void input() //读入
{
int i,count[N]={0};
char s,ch[N];
FILE *fp,*fp1;
for (i=0;i<N;i++)
ch[i]=i;
fp=fopen("原文.txt","r");
if (fp==NULL)
printf ("打开文件失败!\n");
else while ((s=fgetc(fp))!=EOF)
{
for (i=0;i<N;i++)
if(s==ch[i])
{
count[i]++;
break;
}
}
printf ("\n");
fclose(fp);
n=0;
for (i=0;i<N;i++)
if (count[i]!=0)
{
HT[n].ch=ch[i];
HT[n].weight=count[i];
n++;
}
fp1=fopen ("概率.txt","w");
for (i=0;i<n;i++)
fprintf (fp1,"%-10c%d\n",HT[i].ch,HT[i].weight);
fclose(fp1);
}
void buildtree()//建树
{
int i,j,min,hypomin,Min,Hmin;
m=2*n-1;
for (i=n;i<m;i++)
{
Min=0;Hmin=0;
min=32767;hypomin=32767;
for (j=0;j<i;j++)
if (HT[j].parent==0&&HT[j].weight<min)
{
hypomin=min;
Hmin=Min;
min=HT[j].weight;
Min=j;
}
else if (HT[j].parent==0&&HT[j].weight<hypomin)
{
hypomin=HT[j].weight;
Hmin=j;
}
HT[i].weight=min+hypomin;
HT[i].lc=Min;
HT[i].rc=Hmin;
HT[Min].parent=i;
HT[Hmin].parent=i;
HT[Min].data=0;
HT[Hmin].data=1;
}
}
void code1()//编码
{
int i,j,k,f,cd[N];
char s;
FILE *fp1,*fp2;
fp1=fopen("原文.txt","r");
fp2=fopen("原文到二进制流.txt","w");
if (fp1==NULL)
printf ("打开文件失败!\n");
else while ((s=fgetc(fp1))!=EOF)
{
for (i=0;i<n;i++)
if(s==HT[i].ch)
{
k=0;
for (j=i,f=i;f<m-1;f=HT[f].parent,j=f)
{
cd[N-k-1]=HT[j].data;
k++;
}
for (i=N-k;i<N;i++)
fprintf (fp2,"%d",cd[i]);
break;
}
}
fclose(fp2);
fclose(fp1);
}
void compress()//压缩
{
int k,temp=0,a[6]={32,16,8,4,2,1};
char s1,s2;
len=0;
FILE *fp2,*fp3;
fp2=fopen("原文到二进制流.txt","r");
fp3=fopen("压缩后.txt","w");
if (fp2==NULL)
printf ("打开文件失败!\n");
else while ((s1=fgetc(fp2))!=EOF)
{
k=len%6;
if (s1=='1')
temp=temp+a[k];
len++;
if (len%6==0)
{
s2=temp+48;
fprintf (fp3,"%c",s2);
temp=0;
}
}
if (len%6!=0)
{
s2=temp+48;
fprintf (fp3,"%c",s2);
}
fclose(fp3);
fclose(fp2);
}
void code2()//将字符流转化为0,1字符流
{
int k,temp,b,a[6]={32,16,8,4,2,1};
long unsigned int count;
char s1,s2;
FILE *fp3,*fp4;
count=0;
fp3=fopen("压缩后.txt","r");
fp4=fopen("解压的二进制流.txt","w");
if (fp3==NULL)
printf ("打开文件失败!\n");
else while ((s1=fgetc(fp3))!=EOF)
{
temp=(int)s1;
temp=temp-48;
k=0;
while (k<6&&count<len)
{
count++;
b=temp;
temp=temp/a[k];
s2=temp+48;
fprintf (fp4,"%c",s2);
temp=b%a[k];
k++;
}
}
fclose(fp4);
fclose(fp3);
}
void code3()//解码
{
int k,temp;
char s1;
k=m-1;
FILE *fp4,*fp5;
fp4=fopen("解压的二进制流.txt","r");
fp5=fopen("解压后的原文.txt","w");
if (fp4==NULL)
printf ("打开文件失败!\n");
else while ((s1=fgetc(fp4))!=EOF)
{
temp=(int)s1;
temp=temp-48;
if (HT[k].lc!=-1)
{
if (temp==1)
k=HT[k].rc;
else k=HT[k].lc;
}
if (HT[k].lc==-1)
{
fprintf (fp5,"%c",HT[k].ch);
k=m-1;
}
}
fclose(fp5);
fclose(fp4);
}
void compare()
{
int flag=0;
char s1,s2;
FILE *fp1,*fp5;
fp1=fopen("原文.txt","r");
fp5=fopen("解压后的原文.txt","r");
while ((s1=fgetc(fp1))!=EOF&&(s2=fgetc(fp5))!=EOF)
if (s1!=s2)
flag=1;
if (flag==1)
printf ("解码失败\n");
else printf ("解码成功\n");
fclose(fp5);
fclose(fp1);
}
int main(int argc, char* argv[])
{
init();
input();
buildtree();
code1();
compress();
code2();
code3();
compare();
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -