哈夫曼编码/译码器

  • Post author:
  • Post category:其他



欢迎加qq群:453398542 学习讨论,会定期分享资料课程,解答问题。
哈夫曼编码/译码器
【问题描述】
根据给定的一组电文,设计该电文的哈夫曼编码。
(1)初始化(Initialization):从终端读入字符集,大小n,随机产生包含n个字符的字符集存入文件中,然后统计每个字符出现的次数作为各字符的权值,以此建立哈夫曼树;
(2)编码(Coding):根据建立的哈夫曼树,对数据进行编码,然后将结果存入文件codefile中;
(3)译码(Decoding):利用已建好的哈夫曼树将文件codefile中的代码进行译码,结果存入文件textfile中。
随机产生的字符要足够多,不允许手工输入。
#include<stdio.h>  
#include<stdlib.h>  
#include<string.h> 
#include<time.h> 
typedef struct{
	char a;
	int weight=0;
}W;
typedef struct{  
      int weight;  
      int parent,lchild,rchild;  
      char data;  
}HTNode,*HuffmanTree;   
typedef char **HuffmanCode;  
void Suiji(char *a, int n){
    char all[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    srand(time(0));
    for (int i=0;i<n-1;i++){
        a[i]=all[rand()%62]; 
    }
    a[n-1]='\0';
    FILE *fp;
    fp=fopen("text.txt","w");
    fprintf(fp,"%s",a);
    fclose(fp);
}
void Weight(char *a,W w[],int &n){
	char *p;
	p=a;
	int i=0,j=0,k;
	w[i].a=*p;
	w[i].weight++;
	p++;
	while(*p!='\0'){
		for(k=0;k<=i;k++){
			if(w[k].a==*p){
				w[k].weight++;
				break;  
			}
		}
		if(k>i){
			i++;
			w[i].a=*p;
			w[i].weight++;
		}
		p++;
	}
	n=i+1;
	for(i=0;i<n;i++)
		printf("%d",w[i].weight);
	printf("\n");
}
void Select(HuffmanTree HT,int n,int &s1,int &s2){  
    int i=1;  
    int min1=10000,min2=10000;  
    s1=s2=0;  
    while(i<=n){  
        if(HT[i].parent==0){  
            if(min1>HT[i].weight){  
                min2=min1;  
                s2=s1;  
                min1=HT[i].weight;  
                s1=i;  
            }  
            else if(min2>HT[i].weight){  
                s2=i;  
                min2=HT[i].weight;  
            }  
        }  
        i++;  
    }  
}   
void CreateHuffman(HuffmanTree &HT,char *a,W w[],int n){  
    int i,s1,s2;  
    int m=2*n-1;  
    if(n<=1)  
        return ;  
    HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));  
    for(i=0;i<=n;i++){  
        HT[i].weight=w[i].weight;  
        HT[i].data=w[i].a;  
        HT[i].lchild=0;  
        HT[i].parent=0;  
        HT[i].rchild=0;  
    }  
    for(;i<=m;++i){  
        HT[i].weight=0;  
        HT[i].lchild=0;  
        HT[i].parent=0;  
        HT[i].rchild=0;  
    }  
    for(i=n+1;i<=m;i++){//建立哈夫曼树  
        s1=s2=0;  
        Select(HT,i-1,s1,s2);  
        HT[s1].parent=i;HT[s2].parent=i;  
        HT[i].lchild=s1;HT[i].rchild=s2;  
        HT[i].weight=HT[s1].weight+HT[s2].weight;  
    }  
}   
void HuffmanCoding(HuffmanTree HT,HuffmanCode &HC,int n){//求出n个字符的哈夫曼编码HC  
    int i;  
    HC=(HuffmanCode)malloc((n+1)*sizeof(char*));  
    char *cd=(char*)malloc(n*sizeof(char));  
    cd[n-1]='\0';  
    for(i=1;i<=n;++i){  
        int start=n-1;  
        for(int 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);  
    }  
    for(i=1;i<=n;i++){  
       printf("%c %d的编码为: %s\n",HT[i-1].data,HT[i-1].weight,HC[i]);  
    }  
    free(cd);
	FILE *fp;
    fp=fopen("codefile.txt","w");
    for(i=1;i<=n;i++){  
       fprintf(fp,"%s",HC[i]);  
    }  
    fclose(fp);
}  
void HuffmanDecode(HuffmanTree HT,int n){  
    char decode[100];  
    int i,len,p;  
    FILE *fp,*fp1;
    fp=fopen("codefile.txt","r"); 
    fscanf(fp,"%s",decode);  
    fclose(fp);    
    len=strlen(decode);  
    p=2*n-1;  
    printf("该编码的译码结果为:\n"); 
	fp1=fopen("textfile.txt","w");
    for(i=0;i<=len;i++){  
        if(HT[p].lchild==0&&HT[p].rchild==0){  
            printf("%c",HT[p-1].data); 
			fprintf(fp1,"%c",HT[p-1].data);
            p=2*n-1;  
        }  
        if(decode[i]=='0')  
            p=HT[p].lchild;  
        else if(decode[i]=='1')  
            p=HT[p].rchild;  
    }   
	fclose(fp1);
}  
int main(){
	int n;
	char a[500];
	W w[100];
	HuffmanTree Ht;
	HuffmanCode Hc;
	printf("输入字符个数:");
	scanf("%d",&n);
    Suiji(a,n+1);
    printf("%s",a);
    printf("\n");
    Weight(a,w,n);
    CreateHuffman(Ht,a,w,n);
    HuffmanCoding(Ht,Hc,n);
    HuffmanDecode(Ht,n);
    return 0;
}



版权声明:本文为CSDN_buyi原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。