我的这个哈夫曼编译器第一次运行的时候怎么那么慢?那位高手给点建议

yejieku 2009-05-12 05:45:45
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXSTRING 27 //字符集最大个数
typedef struct {
int weight; //权值
char c;
int parent,lchild,rchild;
}HTNode,*HuffmanTree; //哈夫曼树
typedef char * * HuffmanCode; //动态分配数值存储哈夫曼编码表
void Initialization(int &n,char a[],int w[]){
printf("请输入字符集的大小:\n");
scanf("%d",&n);
printf("请依次输入这%d个字符(连续输入中间不含空格):\n",n);
getchar(); //滤去回车符
for(int i=0;i<n;i++)
scanf("%c",&a[i]);
printf("请依次输入这%d个字符的权值(空格区分开):\n",n);
getchar(); //滤去回车符
for(i=0;i<n;i++)
scanf("%d",&w[i]);
getchar(); //滤去回车符
}//Initialization
void Select(HuffmanTree HT,int i,int &s1,int &s2){
//选择weight最小的两个结点,序号本别为s1和s2
int j=1; //循环计数器
int m;//记录最小权值
while(HT[j].parent!=0&&j<=i)
j++;
m=HT[j].weight;
s1=j; //记录第一个权值最小的HT下标
for(int k=j+1;k<=i;k++){ //选出第一个拥有最小权值的HT
if(HT[k].parent==0)
if(m>HT[k].weight){
s1=k;
m=HT[k].weight;
}
}//for
j=1; //计数器清零,开始寻找第二个最小权值
while((HT[j].parent!=0&&j<=i)||j==s1)
j++;
m=HT[j].weight;
s2=j;
for(k=j+1;k<=i;k++){ //选出第二个拥有最小权值的HT
if(HT[k].parent==0&&k!=s1)
if(m>HT[k].weight){
s2=k;
m=HT[k].weight;
}
}//for
}//Select
int HuffmanCoding(HuffmanTree &HT,int n,char a[],int w[],int &tag){//构造哈夫曼树
FILE *fp;
HuffmanTree p;
int s1,s2;
int i;
if(n<=1) return 1;
int 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).c=a[i-1];(*p).parent=0;(*p).lchild=0;(*p).rchild=0;
}
for(;i<=m;i++, p++){
(*p).weight=0;(*p).c='0';(*p).parent=0;(*p).lchild=0;(*p).rchild=0;
}
for(i=n+1;i<=m;i++){ //构建哈夫曼树
Select(HT,i-1,s1,s2);
HT[s1].parent=i;HT[s2].parent=i;
HT[i].lchild=s2;HT[i].rchild=s1;
HT[i].weight=HT[s1].weight+HT[s2].weight;
}//for
if((fp=fopen("hfmTree.txt","wb"))==NULL){
printf("file open error\n");
exit(0);
}
for(int j=1;j<=m;j++)
fwrite(&HT[j],sizeof(HTNode),1,fp);
fclose(fp);
tag=1;
return 1;
}//HumanCoding
void Encoding(HuffmanTree &HT,HuffmanCode &HC,int &n,int &tag){
FILE *hfmin,*train,*out;
int c,f,k=1;
char s;
if((train=fopen("ToBeTran.txt","r"))==NULL){
printf("file open error\n");
exit(0);
}
if((out=fopen("CodeFile.txt","wb"))==NULL){
printf("file open error\n");
exit(0);
}
if(tag==0){ //判定哈夫曼树是否在内存中
HT=(HuffmanTree)malloc((2*MAXSTRING)*sizeof(HTNode)); // 0号单元未用
if((hfmin=fopen("hfmTree.txt","rb"))==NULL){
printf("file open error\n");
exit(0);
}//if
for(int i=1;fread(&HT[i],sizeof(HTNode),1,hfmin)==1;++i);
n=(i+1)/2;
fclose(hfmin);
}
HC=(HuffmanCode)malloc((n+1)*sizeof(char *));//分配n个字符编码的头指针的向量
char * cd=(char *)malloc(n*sizeof(char)); //分配求编码的工作空间
cd[n-1]='\0';
for(int i=1;i<=n;++i){ //逐个字符求哈夫曼编码
int 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';
}//for
HC[i]=(char *)malloc((n-start)*sizeof(char));//为第i个字符编码分配空间
strcpy(HC[i],&cd[start]);
}//for
free(cd); //释放工作空间
while((s=fgetc(train))!=EOF){
k=1;
while(s!=HT[k].c)
k++;
fputs(HC[k],out);
}
tag=1;
fclose(train);
fclose(out);
}//Encoding
void Decoding(HuffmanTree &HT,int &n,int &tag){
FILE *in1,*in2,*out;
char c;
if(tag==0){ //判定哈夫曼树是否在内存中
HT=(HuffmanTree)malloc((2*MAXSTRING)*sizeof(HTNode)); // 0号单元未用
if((in1=fopen("hfmTree.txt","rb"))==NULL){
printf("还未进行初始化\n");
exit(0);
}//if
for(int i=1;fread(&HT[i],sizeof(HTNode),1,in1)==1;++i);
n=(i+1)/2;
fclose(in1);
}
if((in2=fopen("CodeFile.txt","r"))==NULL){
printf("file open error\n");
exit(0);
}
if((out=fopen("TextFile.txt","w"))==NULL){
printf("file open error\n");
exit(0);
}
int i=2*n-1;
while((c=fgetc(in2))!=EOF){
if(HT[i].lchild==0){
ungetc(c,in2);
fputc(HT[i].c,out);
i=2*n-1;
}//if
else{
if(c=='0')
i=HT[i].lchild;
else
i=HT[i].rchild;
}//else
if((c=fgetc(in2))==EOF)
fputc(HT[i].c,out);
ungetc(c,in2);
}//while
tag=1;
fclose(in2);
fclose(out);
}//Decoding
void Print(){
FILE *in,*out;
char c; int i=0;
if((in=fopen("CodeFile.txt","r"))==NULL){
printf("file open error\n");
exit(0);
}
if((out=fopen("CodePrin.txt","w"))==NULL){
printf("file open error\n");
exit(0);
}
while((c=fgetc(in))!=EOF){
printf("%c",c); fputc(c,out);
i++;
if(i%50==0){
printf("\n");
fputc('\n',out);
}
}//while
printf("\n");
fclose(in);
fclose(out);
}//Print
int Tree_print(HuffmanTree HT,int n,int tag){ //印哈夫曼树
FILE *out;
if(tag==0){
printf("内存中不存在哈夫曼树,请进行初始化\n");
return 0;
}
if((out=fopen("TreePrint.txt","wb"))==NULL){
printf("file open error\n");
exit(0);
}
printf("char\tweight\tparent\tlchild\trchild\n");
fputs("char\tweight\tparent\tlchild\trchild\n",out);
for(int i=1;i<2*n;i++){
printf("%4c\t%6d\t%6d\t%6d\t%6d\n",HT[i].c,HT[i].weight,HT[i].parent,HT[i].lchild,HT[i].rchild);
fprintf(out,"%4c\t%6d\t%6d\t%6d\t%6d\n",HT[i].c,HT[i].weight,HT[i].parent,HT[i].lchild,HT[i].rchild);
}
fclose(out);
return 1;
}//Tree_print
void main(){
char a[MAXSTRING],choice;
int w[MAXSTRING];
int n; //字符集个数
int tag=0;//初始化标志域
HuffmanTree ht;
HuffmanCode hc;
do{
printf("\t\t\t功能表\nI:初始化 E:编码 D:译码 P:印代码文件 T:印哈夫曼树 Q:退出\n");
scanf("%c",&choice);
getchar(); //滤去回车符
switch(choice){
case 'I':
Initialization(n,a,w);
HuffmanCoding(ht,n,a,w,tag);
break;
case 'D':
Decoding(ht,n,tag);
break;
case 'E':
Encoding(ht,hc,n,tag);
break;
case 'P':
Print();
break;
case 'T':
Tree_print(ht,n,tag);
break;
case 'Q':
break;
default:
printf("输入有误\n");
}
}while(choice!='Q');
}//main
...全文
88 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

33,311

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧