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

📄 hfm.cpp

📁 数据结构实习题目哈弗曼编码-译码系统的完整设计
💻 CPP
字号:
#include<string.h>
#include<ctype.h>
#include<malloc.h>
#include<stdio.h>
#include<process.h>
#include<limits.h>
//定义全局变量来存放相关字符及相应的权值
char string[100];
int w[100]; 
//赫夫曼树和赫夫曼编码的存储表示 
typedef struct HTNode1
{
   unsigned int weight;
   char ch;//存放字符 
   unsigned int parent,lchild,rchild;
}HTNode,*HuffmanTree; //动态分配数组存储赫夫曼树
typedef char **HuffmanCode; //动态分配数组存储赫夫曼编码表 
HuffmanCode HC;
HuffmanTree *HT2;




int min1(HuffmanTree t,int i)
 { /* 函数void select()调用 */
   int j,flag;
   unsigned int k=UINT_MAX; /* 取k为不小于可能的值 */
   for(j=1;j<=i;j++)
     if(t[j].weight<k&&t[j].parent==0)
       k=t[j].weight,flag=j;
   t[flag].parent=1;
   return flag;
 }

 void select(HuffmanTree t,int i,int *s1,int *s2)
 { /* s1为最小的两个值中序号小的那个 */
   int j;
   *s1=min1(t,i);
   *s2=min1(t,i);
   if(*s1>*s2)
   {
     j=*s1;
     *s1=*s2;
     *s2=j;
   }
 }

HTNode **HuffmanCoding(HuffmanTree *HT,HuffmanCode *HC,int n) 
 { /* 构造赫夫曼树HT,并求出n个字符的赫夫曼编码HC */
   int m,i,s1,s2,start;
   unsigned c,f;
   HuffmanTree p;
   char *cd;
   if(n<=1)
     return 0;
   m=2*n-1;
   *HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode)); /* 0号单元未用 */
   for(p=*HT+1,i=1;i<=n;++i,++p)
   {
     (*p).weight=w[i-1];
     (*p).parent=0;
     (*p).lchild=0;
     (*p).rchild=0;
     (*p).ch='#';//字符初始化为'#'
	
   }
   for(;i<=m;++i,++p)
   { (*p).parent=0;
     (*p).ch='#';//字符初始化为'#'
   }
   for(i=n+1;i<=m;++i) /* 建赫夫曼树 */
   { /* 在HT[1~i-1]中选择parent为0且weight最小的两个结点,其序号分别为s1和s2 */
     select(*HT,i-1,&s1,&s2);
     (*HT)[s1].parent=(*HT)[s2].parent=i;
     if(s1<=n) (*HT)[s1].ch=string[s1-1];
	 if(s2<=n)	(*HT)[s2].ch=string[s2-1];
     (*HT)[i].lchild=s1;	 
     (*HT)[i].rchild=s2;	 
     (*HT)[i].weight=(*HT)[s1].weight+(*HT)[s2].weight;
   }

   /* 从叶子到根逆向求每个字符的赫夫曼编码 */
   *HC=(HuffmanCode)malloc((n+1)*sizeof(char*));
   /* 分配n个字符编码的头指针向量([0]不用) */
   cd=(char*)malloc(n*sizeof(char)); /* 分配求编码的工作空间 */
   cd[n-1]='\0'; /* 编码结束符 */
   for(i=1;i<=n;i++)
   { /* 逐个字符求赫夫曼编码 */
     start=n-1; /* 编码结束符位置 */
     for(c=i,f=(*HT)[i].parent;f!=0;c=f,f=(*HT)[f].parent)
     /* 从叶子到根逆向求编码 */
       if((*HT)[f].lchild==c)
         cd[--start]='0';
       else
         cd[--start]='1';
     (*HC)[i]=(char*)malloc((n-start)*sizeof(char));
     /* 为第i个字符编码分配空间 */
     strcpy((*HC)[i],&cd[start]); /* 从cd复制编码(串)到HC */
   }
   free(cd); /* 释放工作空间 */
    return HT;
}


void Initialization()
{
	FILE *fp1;
	
	int j,tempnum;
	char ch;
	if((fp1=fopen("Init.txt","r"))==NULL)
	{
		printf("read Init.txt failed! \n ");
		return ;

	}
	
	j=0;
	fgets(string,100,fp1);
	tempnum=0;
	while(!feof(fp1))
	{	ch=fgetc(fp1);	
		if(ch>='0'&&ch<='9')	
		{  
			tempnum=tempnum*10+(ch-48);
		    w[j]=tempnum;
		}
		else {tempnum=0;j++;}	
		
	}
	
	
	fclose(fp1);
	


}

void Encoding()
{	
   FILE *fp1,*fp2;
   int i;
   char ch;
   if((fp1=fopen("ToBeTran.txt","r"))==NULL)
	{
		printf("open ToBeTran.txt failed! \n");
		return ;

	}
   if((fp2=fopen("CodeFile.txt","w"))==NULL)
	{
		printf("write CodeFile.txt failed! \n ");
		return ;

	}
   while(!feof(fp1))
   {
		ch=fgetc(fp1);
		for(i=0;i<strlen(string)-1;i++)
		{
			if(string[i]==ch) fputs(HC[i+1],fp2);
		}


   }
   fclose(fp1);
   fclose(fp2);


}




void Decoding()
{
	FILE *fp1,*fp2;
	int leftch,rightch,l,r,n;
//	int n=strlen(string)-1;
	char ch;


	if((fp1=fopen("CodeFile.txt","r"))==NULL)
	{
		printf("read CodeFile.txt failed! \n ");
		return ;
	}
	if((fp2=fopen("TextFile.txt","w"))==NULL)
	{
		printf("write TextFile.txt failed! \n ");
		return ;
	}

	n=strlen(string)-1;
	leftch=(*HT2)[2*n-1].lchild;
	rightch=(*HT2)[2*n-1].rchild;
	while(!feof(fp1))
	{  ch=fgetc(fp1);
		if(ch=='0') 
			{	
				l=leftch;
				leftch=(*HT2)[leftch].lchild;
				rightch=(*HT2)[l].rchild;
				if(leftch==0)
					{
						//printf("*");
					
						printf("%c",(*HT2)[l].ch);
						fputc((*HT2)[l].ch,fp2);
						leftch=(*HT2)[2*n-1].lchild;
						rightch=(*HT2)[2*n-1].rchild;
					}


			}
		 else if(ch=='1')
				{
					r=rightch;
					rightch=(*HT2)[rightch].rchild;
					leftch=(*HT2)[r].lchild;
					if(leftch==0)
						{
							//printf("*");

							printf("%c",(*HT2)[r].ch);
							fputc((*HT2)[r].ch,fp2);
							leftch=(*HT2)[2*n-1].lchild;
							rightch=(*HT2)[2*n-1].rchild;
						}
				}

 
		}
	fclose(fp1);
        fclose(fp2);





}

void Code_Print()
{
	FILE *fp1,*fp2;
	char str_print[51];
	if((fp1=fopen("CodeFile.txt","r"))==NULL)
	{
		printf("read CodeFile.txt failed! \n ");
		return ;

	}
	if((fp2=fopen("CodePrin.txt","w"))==NULL)
	{
		printf("write CodePrin.txt failed! \n ");
		return ;

	}

	while(!feof(fp1))
	{
	fgets(str_print,51,fp1);
	puts(str_print);
	printf("\n");
	fputs(str_print,fp2);
	fputc('\n',fp2);
	}
   fclose(fp1);
   fclose(fp2);



}
void Tree_Print(int j)
{	
	if(j!=0)
	{
		printf("%d",(*HT2)[j].weight);
		if((*HT2)[j].lchild!=0)
		{
			printf("(");
			Tree_Print((*HT2)[j].lchild);
			if((*HT2)[j].rchild!=0)
			{printf(",");}
			Tree_Print((*HT2)[j].rchild);
			printf(")");

		}

	}

}

void compare()
{
	FILE *fp1,*fp2;
	char ch;
	int sum,i;
	if((fp1=fopen("CodeFile.txt","r"))==NULL)
	{
		printf("read ToBeTran.txt failed! \n ");
		return ;

	}
	if((fp2=fopen("CodeFile_Askm.txt","w"))==NULL)
	{
		printf("write CodeFile_Askm.txt failed! \n ");
		return ;

	}
	while(!feof(fp1))
{
		sum=0;
		for(i=1;i<=32;i++)
		{
			if(!feof(fp1))
			{
				ch=fgetc(fp1);
				if(ch=='1')
				sum=sum+1;
				sum=sum<<1;
			}
			}
		fwrite(&sum,sizeof(int),1,fp2);
}

fclose(fp1);
fclose(fp2);

	
}

void main()
{	
int n,i;
char c='#';
HuffmanTree HT1;
FILE *fp2,*fp3;
if((fp2=fopen("HfmTree.txt","wb"))==NULL)
	{
		printf("write HfmTree.txt failed! \n ");
		return ;

	}
	if((fp3=fopen("HfmTree.txt","rb"))==NULL)
	{
		printf("read HfmTree.txt failed! \n ");
		return ;

	}
	while(c!='Q')
	{	printf("\n");
	printf("1、初始化(I)\n2、编码(E)\n3、比较两种编码(C)\n4、译码(D)\n5、打印代码文件(P)\n6、打印哈夫曼树(T)\n7、退出(Q)\n");
	 printf("请输入您的选择:");c=getchar();
	 switch(c)
	 {
	 case 'I':
     Initialization();
	n=strlen(string)-1;
	HT2=HuffmanCoding(&HT1,&HC,n);
	for(i=1;i<=2*n-1;++i)
	{
		if(fwrite(&((*HT2)[i]),sizeof(struct HTNode1),1,fp2)!=1)
		printf("write error\n");

	}
	fclose(fp2);
	  getchar();
	  break;
	 case 'E':
		  Encoding();
		 getchar();
		 break;
	 case 'C':
		 compare();
		 getchar();
		 break;
	 case 'D':
		 Decoding();
		 getchar();
		 break;
	 case 'P':
		 Code_Print();
		 getchar();
		 break;
	 case 'T':
		 Tree_Print(2*(strlen(string)-1)-1);
		 getchar();
		 break;
	 case 'Q':
		 break;
	 default :
		 printf("输入格式不对!\n");
		 getchar();
		 break;
	 }
	}


	

/*	for(i=1;i<=2*n-1;++i)
	{
	fread(&((*HT2)[i]),sizeof(struct HTNode1),1,fp3);
	printf("%d%c%d%d%d\n",(*HT2)[i].weight,(*HT2)[i].ch,(*HT2)[i].parent,(*HT2)[i].lchild,(*HT2)[i].rchild);
	}*/
	
	
	
	


	


}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -