📄 hafuuman完美版.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 + -