⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 huffman_32.cpp

📁 多个Huffman编码、解码器的程序
💻 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 + -