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

📄 hafuuman完美版.txt

📁 关于哈夫曼编码的C程序 自动统计并编码
💻 TXT
字号:
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
typedef struct
{
	char data;
	int weight;
	int parent;
	int lchild;
	int rchild;
}HTNode,*hufftree;
typedef char **huffcode;

void huffbuild(hufftree ht,int n)
{
	
	int i,s1,s2,m1,m2,k;
	for(i=n+1;i<=2*n-1;i++)
	{
		m1=m2=32767;
		s1=s2=0;
		for(k=1;k<=i-1;k++)
		{
			if(ht[k].parent==0)
				if(ht[k].weight<m1)
				{
					m2=m1;
					s2=s1;
					m1=ht[k].weight;
					s1=k;				
				}
				else if(ht[k].weight<m2)
				{
					m2=ht[k].weight;
					s2=k;
				}
		}
		ht[s1].parent=i;
		ht[s2].parent=i;
		ht[i].weight=ht[s1].weight+ht[s2].weight;
		ht[i].lchild=s1;
		ht[i].rchild=s2;
	}
}//huffbuild
void huffcodeing(huffcode hc,hufftree ht,int n)
{
	int start,i,c,f;
	char *cd;	
	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));
		strcpy(hc[i],&cd[start]);
	}
	free(cd);
}//huffcode
void yima(hufftree ht,int n,FILE*fp,FILE*fb)
{
	int d;
	char ch;
	d=2*n-1;
	while(!feof(fp))
	{
		if(ht[d].lchild)
		{
			ch=fgetc(fp);
			if(ch=='0')
				d=ht[d].lchild;
			else
				d=ht[d].rchild;
		}
		else
		{
			printf("%c",ht[d].data);
			fputc(ht[d].data,fb);
			d=2*n-1;
		}
	}
}//yima
void bianma(hufftree ht,huffcode hc,int n,FILE *fp,FILE *fb)
{
	int i,k;
	char ch;
	while(!feof(fp))
	{
		ch=fgetc(fp);
		for(i=1;i<=n;i++)
		{
			if(ch==ht[i].data)
			{
				printf("%s",hc[i]);
				fprintf(fb,"%s",hc[i]);
				break;
			}
		}
	}
}//bianma

void main()
{
	int i,l,k,n,x,sum,m,j;
	char b,str1[20],str[20],str2[20],strx[10000],ch;
	FILE * fp,*fb;
	hufftree ht;
	huffcode hc;
	while(1)
	{
		printf("请输入字符集的大小n=");
        gets(str1);
		k=1;
		if(str1[0]=='\0')
			printf("\n输入有误,请输入正整数。\n");
		else
		{
			for(i=0;str1[i]!='\0';i++)
			{
				if(str1[i]<'0'||str1[i]>'9')
				{
					printf("\n输入有误,请输入正整数。\n");
					k=0;
					break;
				}
			}
			if(k)
			{n=atoi(str1); break;} 
			else
				printf("出错重输-->\n\n");
		}
	}
	for(i=1;i<=10;i++)
	{
		printf("****************");
	}
	m=2*n-1;
	hc=(huffcode)malloc((n+1)*sizeof(char*));
	if(!hc) 
	{
		printf("分配内存失败。按任意键继续。");
		getchar();
        exit(1);
	}
	ht=(hufftree)malloc((m+1)*sizeof(HTNode));
	if(!ht) 
	{
		printf("分配内存失败。按任意键继续。");
		getchar();
        exit(1);
	}
	for(l=1;l<=m;l++)
	{
		ht[l].data=0;
		ht[l].parent=0;
		ht[l].lchild=0;
		ht[l].rchild=0;
		ht[l].weight=0;
	}
	printf("\n输入结点字符及与其对应得权值:\n注意:结点值为单一字符,权值为正整数\n\n");
	for(i=1,x=0,sum=0;i<=n;i++)
	{
		if(x!=6)
		{
			printf("\n请输入结点字符:");
			gets(str1);
			if(str1[1]!='\0')
			{
				printf("\t非法输入!结点字符只能为1个字符,并以回车确定。请重输。\n注意:非法输入达到6次您将被强行退出!\n");
				x++;
				i--;
				continue;
			}
			else
			{
				str[i]=str1[0];
				for(k=1,j=1;j<i;j++)
				{
					if(str[j]==str[i])
					{
						printf("\t非法输入!这个字符已经输入过。请重输。\n注意:非法输入达到6次您将被强行退出!\n");
						x++; i--; k=0; break;
					}
				}
				if(!k) continue;
				ht[i].data=str1[0];
			}
			printf("\n请输入权值:");
			gets(str1);
			if(str1[0]=='\0')
			{
				printf("\t非法输入!权值只能为正整数。请重输。\n注意:非法输入达到6次您将被强行退出!\n");
				x++;
				i--;
				continue;
			}
			else
			{
				for(k=0;str1[k]!='\0';k++);
				k=k-1;
				for(j=0;str1[j]!='\0';j++)
				{
					if(str1[j]<'0'||str1[j]>'9')
					{
						printf("\t非法输入!权值只能为正整数。请重输。\n注意:非法输入达到6次您将被强行退出!\n");
						x++; i--; sum=0; break;
					}
					else
					{
						sum+=(str1[j]-'0')*(int)pow(10,k);
						k--;
					}
				}
			}
			if(sum)
			{
				ht[i].weight=sum;
				sum=0;
				printf("\t%d,结点字符值:%c    权值=%d",i,ht[i].data,ht[i].weight);
			}
		}//if(x!=6)
		else
		{
			printf("\n非法输入已经达到6次,您将被强行退出\n\t按任意键确定:");
			getchar();
			exit(1);
		}
	}//for
	while(1)
	{
		printf("\n\n您输入的结点字符值及其对应权值为:\n");
		for(i=1;i<=n;i++)
			printf("\t%d,结点值=%c  权值=%d\n",i,ht[i].data,ht[i].weight);
		printf("\n\n确定请按y,更改按其他任意键。回车确定输入。\n\n");
		gets(str1);
		if((str1[0]=='y'||str1[0]=='Y')&&str1[1]=='\0')
			break;
		else if(str1[1]=='\0')
		{
			while(1)
			{
				printf("\n进入修改模式。键入q退出更改\n现在请输入您要更改对象的编号:");
				gets(str1);
				if((str1[0]=='q'||str1[0]=='Q')&&str1[1]=='\0') break;
				else
				{
					for(i=0,sum=0;str1[i]!='\0';i++)
					{
						for(k=0;str1[k]!='\0';k++);
						k=k-1;
						if(str1[i]<'0'||str1[i]>'9')
						{
							printf("\n输入格式不对,请重新输入\n");
							sum=0; break;
						}
						else
						{
							sum+=(str1[i]-'0')*(int)pow(10,k);
							k--;
						}
					}
					if(sum<=n&&sum>=1)
					{
						printf("您要更改的是:%d   结点值=%c  权值=%d\n",sum,ht[sum].data,ht[sum].weight);
						printf("\t新的结点值=");
						while(1)
						{
							gets(str2);
							if(str2[1]!='\0')
								printf("输入有误!结点字符只能为1个字符,并以回车确定。请重输。\n\n\t新的结点值=");
							else
							{
								ht[sum].data=str2[0]; break;
							}
						}
						printf("\t新的对应权值=");
						while(1)
						{
							gets(str1);
							if(str1[0]=='\0')
							{
								printf("\t输入有误!权值只能为正整数。请重输。\n\n\t新的对应权值=");
								continue;
							}
							else
							{
								b=0;
								for(k=0;str1[k]!='\0';k++);
								k=k-1;
								for(j=0;str1[j]!='\0';j++)
								{
									if(str1[j]<'0'||str1[j]>'9')
									{
										printf("\t输入有误!权值只能为正整数。请重输。\n\n\t新的对应权值=");
										b=0; break;
									}
									else
									{
										b+=(str1[j]-'0')*(int)pow(10,k);
										k--;
									}
								}
							}
							if(b)
							{
								ht[sum].weight=b; break;
							}
			
						}				
					}
					else if(sum)
					{
						printf("\n不存在这个序号,修改失败。按任意键继续。");
						getchar();
					}
				}//else
			}//while
		}//if else
		else
			printf("输入有误!只能输入y或其他任意一个键,并按回车确定。");
	}//while
	huffbuild(ht,n);
	huffcodeing(hc,ht,n);
	for(i=1;i<=n;i++)
		printf("\t%d,结点值=%c  权植=%d  字符编码:%s\n\n",i,ht[i].data,ht[i].weight,hc[i]);
	printf("\n输入完毕!\n");
	while(1)
	{
		printf("\n请选择服务种类: \n键入1为编码\t键入2为译码\n");
        gets(str1);
		if(str1[0]=='1'&&str1[1]=='\0')
		{
			printf("\t我要吊入文件,并把所掉文件编码。请键入a,以回车确定\n");
			printf("\t我要自己写文章,并把所写文章进行编码。请键入b,以回车确定\n");
			gets(str1);
			if(str1[0]=='a'&&str1[1]=='\0')
			{
				printf("\n请输入吊入文件路径:");
				gets(str);
				if((fp=fopen(str,"r"))==NULL)
				{
					printf("该文件不存在或这有错误,不能打开。SORRY!.按任意键加回车继续");
					getchar();
					continue;
				}
				/*	while(!feof(fp))
				{
				ch=fgetc(fp);
				for(i=1;ht[i].data!=ch&&i<=n;i++);
				if(i>n)
				{
				printf("检测发现所吊入文件中含有不匹配字符。按任意键加回车继续\n");
				getchar();
				break;
				}
				else
				printf("\n文件合法\n");
			}*/
				while(1)
				{
					printf("请输入编码结果的保存路径:");
					gets(str2);
					if((fb=fopen(str2,"wt"))==NULL)
					{
						printf("该文件不存在或着路径输入有误,不能打开文件。SORRY!.按任意键加回车继续");
						getchar();
						continue;
					}
					break;
				}
				
				bianma(ht,hc,n,fp,fb);
				fclose(fp);
				fclose(fb);
			}//if(str1[0]=='a'&&str1[1]=='\0')
			else if(str1[0]=='b'&&str1[1]=='\0')
			{
				printf("\n请输入所写内容保存路径:");
				gets(str);
				if((fp=fopen(str,"wt+"))==NULL)
				{
					printf("路径输入有误,不能创建。SORRY!.按任意键加回车继续");
					getchar();
					continue;
				}
				printf("\n\t有效路径!\n开始输入您要写的文章(以回车结束输入):");
				gets(strx);
				fprintf(fp,"%s",strx);
				rewind(fp);
				printf("\n\t\t输入完毕!\n");
				while(1)
				{
					printf("请输入编码结果的保存路径:");
					gets(str2);
					if((fb=fopen(str2,"wt+"))==NULL)
					{
						printf("该文件不存在或着路径输入有误,不能打开文件。SORRY!.按任意键加回车继续");
						getchar();
						continue;
					}
					break;
				}
				bianma(ht,hc,n,fp,fb);
				fclose(fp);fclose(fb);
			}//else if(str1[0]=='b'&&str1[1]=='\0'
			else
			{
				printf("输入有误!只能在a或b中选一个输入并以回车确定!");
				continue;
			}
		}//if(str1[0]=='1'&&str[1]=='\0')
		else if(str1[0]=='2'&&str1[1]=='\0')
		{
			printf("\t我要吊入文件,并把所掉文件译码。请键入a,以回车确定\n");
			printf("\t我要自己写编码,并把所写编码进行译码。请键入b,以回车确定\n");
			gets(str1);
			if(str1[0]=='a'&&str1[1]=='\0')
			{
				printf("\n请输入吊入文件路径:");
				gets(str);
				if((fp=fopen(str,"r"))==NULL)
				{
					printf("\n该文件不存在或这有错误,不能打开。SORRY!.按任意键加回车继续\n");
					getchar();
					continue;
				}
				while(1)
				{
					printf("请输入译码结果的保存路径:");
					gets(str2);
					if((fb=fopen(str2,"wt"))==NULL)
					{
						printf("\n该文件不存在或着路径输入有误,不能打开文件。SORRY!.按任意键加回车继续\n");
						getchar();
						continue;
					}
					break;
				}
				yima(ht,n,fp,fb);
				fclose(fp);
				fclose(fb);
			}
			else if(str1[0]=='b'&&str1[1]=='\0')
			{
				printf("\n请输入所写内容保存路径:");
				gets(str);
				if((fp=fopen(str,"wt+"))==NULL)
				{
					printf("\n路径输入有误,不能创建。SORRY!.按任意键加回车继续\n");
					getchar();
					continue;
				}
				printf("\n\t有效路径!\n开始输入您要写的文章(以回车结束输入):");
				gets(strx);
				fprintf(fp,"%s",strx);
				rewind(fp);
				printf("\n\t\t输入完毕!\n");
				while(1)
				{
					printf("请输入译码结果的保存路径:");
					gets(str2);
					if((fb=fopen(str2,"wt"))==NULL)
					{
						printf("\n该文件不存在或着路径输入有误,不能打开文件。SORRY!.按任意键加回车继续\n");
						getchar();
						continue;
					}
					break;
				}
				yima(ht,n,fp,fb);
				fclose(fp);
				fclose(fb);
			}
			else
			{
				printf("\n输入有误!只能在a或b中选一个输入并以回车确定!\n");
				continue;
			}
		}
		else
		{
			printf("\n输入有误!只能在1或2中选一个输入并以回车确定!\n");
			continue;
		}
		printf("\n\n\n\t\t任务已完成!!!\n按1键继续编译码,按其他任意键退出。以回车键确定输入");
		gets(str1);
		if(str1[0]=='1'&&str1[1]=='/0')
			continue;
		else if(str[1]=='/0')
			break;
		else
			printf("\n输入有误!只能按1或其他任意键并一回车确定\n");
	}
}

⌨️ 快捷键说明

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