哈夫曼编/译码系统的设计与实现
来源:互联网 发布:pd11 for mac 破解版 编辑:程序博客网 时间:2024/06/05 16:19
问题描述
利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码(解码)。对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统。试为这样的信息收发站设计一个哈夫曼编译码系统。
基本要求
- 初始化(Initialzation)。从数据文件DataFile.data中读入字符及每个字符的权值,建立哈夫曼树HuffTree;
- 编码(EnCoding)。用已建好的哈夫曼树,对文件ToBeTran.data中的文本进行编码形成报文,将报文写在文件Code.txt中
- 译码(Decoding)。利用已建好的哈夫曼树,对文件CodeFile.data中的代码进行解码形成原文,结果存入文件Textfile.txt中
- 输出(Output)。输出DataFile.data中出现的字符以及各字符出现的频度(或概率);输出ToBeTran.data及其报文Code.txt;输出CodeFile.data及其原文Textfile.txt
大致过程
- 首先需要写好哈夫曼树的建立和编码过程
- 其次对于译码,则可以从文件中一次读取一个单词,然后挨个完成译码。分别输出到文件。
对于解码,一次读一个单词的哈夫曼码,依次和之前编好的哈夫曼码进行匹配,直到全部解码完成
数据结构
哈夫曼树节点
typedef struct { int weight; int parent,lchild,rchild;}HufNode;
初始节点
typedef struct { int weight; char data; char code[maxn];//需要被建树的信息}HufCode;
程序模块
(1) 初始化输入数据
void Init(HufCode h[])//初始化输入数据{ FILE *f1=fopen("DataFile.data","r"); for(int i=0;i<alphanumber;++i) fscanf(f1,"%c%d ",&h[i].data,&h[i].weight); fclose(f1);}
(2) 根据数据建立哈夫曼树及将编码保存
void HuffmanTree(HufCode *h2,HufNode *h1,int n){ char str[maxn]; int m=2*n-1; for(int i=0;i<m;++i){ if(i<n)//前n个全部是叶子节点, h1[i].weight=h2[i].weight; else//后面的是还没建成的树 h1[i].weight==0; h1[i].lchild=h1[i].parent=h1[i].rchild=0; } int s1,s2; for(int i=n;i<m;++i){ select(h1,i,s1,s2); h1[s1].parent=i;//建立二叉树 h1[s2].parent=i; h1[i].lchild=s1; h1[i].rchild=s2; h1[i].weight=h1[s1].weight+h1[s2].weight; } str[n]='\0'; int l; for(int i=0;i<n;++i){//从每个叶子节点开始倒序遍历 l=n-1;//倒序赋值字符串 for(int k=i,p=h1[k].parent;p;k=p,p=h1[k].parent){//沿着叶子回溯到根节点 if(k==h1[p].lchild) str[l]='0'; else str[l]='1'; l--; } strcpy(h2[i].code,str+l+1); // printf("%c %s\n",h2[i].data,h2[i].code); }}
(3) 根节点中选择两个最小的根
void select(HufNode *h,int k,int &s1,int &s2)//选择两个最小的值{ int i; for(i=0; i<k && h[i].parent != 0; ++i);//选择一个父节点为0的根节点 s1 = i; for(i=0; i<k; ++i){ if(h[i].parent==0 && h[i].weight<h[s1].weight) s1 = i; } for(i=0; i<k; ++i){ if(h[i].parent==0 && i!=s1) break; } s2 = i; for(i=0; i<k; ++i){ if(h[i].parent==0 && i!=s1 && h[i].weight<h[s2].weight) s2 = i; }}
(4) 编码
void EnCodeing(HufCode hc[]){ FILE *f1=fopen("ToBeTran.data","r"); FILE *f2=fopen("Code.txt","w"); char str[maxn]; while(fscanf(f1,"%s",str)!=EOF) { int len=strlen(str); for(int i=0;i<len;++i){ int x=str[i]-'a'; fprintf(f2,"%s",hc[x].code); } fprintf(f2," "); } fclose(f1); fclose(f2);}
(5) 解码
int Search(HufCode hc[],char *str){ for(int i=0;i<alphanumber;++i) if(strcmp(hc[i].code,str)==0) return i; return -1;}void DeCodeing(HufCode hc[]){ FILE *f1=fopen("CodeFile.data","r"); FILE *f2=fopen("Textfile.txt","w"); char str[maxn]; while(fscanf(f1,"%s",str)!=EOF) { char a[maxn]; memset(a,'\0',sizeof(a)); int len=strlen(str),k=0; for(int i=0;i<len;++i){ a[k]=str[i]; a[k+1]='\0'; int ans=Search(hc,a); if(ans!=-1){ fprintf(f2,"%c",ans+'a'); k=0; continue; } k++; } fprintf(f2," "); } fclose(f1); fclose(f2);}
(6) 输出结果
void OutPut(){ FILE *infile=fopen("DataFile.data","r"); FILE *outfile=fopen("Code.txt","r"); int w; char c; printf("各个字母及其权值\n"); for(int i=0;i<alphanumber;++i){ fscanf(infile,"%c %d ",&c,&w); printf("%c %d ",c,w); } infile=fopen("ToBeTran.data","r"); printf("\n\n待编码的内容:\n"); char str[maxn]; while(fscanf(infile,"%s",str)!=EOF) printf("%s ",str); printf("\n编码后结果:\n"); while(fscanf(outfile,"%s",str)!=EOF) printf("%s ",str); printf("\n\n待解码内容:\n"); infile=fopen("CodeFile.data","r"); while(fscanf(infile,"%s",str)!=EOF) printf("%s ",str); printf("\n解码结果:\n"); outfile=fopen("Textfile.txt","r"); while(fscanf(outfile,"%s",str)!=EOF) printf("%s ",str); printf("\n"); fclose(infile); fclose(outfile);}
全部程序
#include<bits/stdc++.h>using namespace std;const int maxn=1000;const int alphanumber=26;typedef struct { int weight; int parent,lchild,rchild;}HufNode;//HuffmanTree的基本定义typedef struct { int weight; char data; char code[maxn];//需要被建树的信息}HufCode;void Init(HufCode h[])//初始化输入数据{ FILE *f1=fopen("DataFile.data","r"); for(int i=0;i<alphanumber;++i) fscanf(f1,"%c%d ",&h[i].data,&h[i].weight); fclose(f1);}void select(HufNode *h,int k,int &s1,int &s2)//选择两个最小的值{ int i; for(i=0; i<k && h[i].parent != 0; ++i);//选择一个父节点为0的根节点 s1 = i; for(i=0; i<k; ++i){ if(h[i].parent==0 && h[i].weight<h[s1].weight) s1 = i; } for(i=0; i<k; ++i){ if(h[i].parent==0 && i!=s1) break; } s2 = i; for(i=0; i<k; ++i){ if(h[i].parent==0 && i!=s1 && h[i].weight<h[s2].weight) s2 = i; }}void HuffmanTree(HufCode *h2,HufNode *h1,int n){ char str[maxn]; int m=2*n-1; for(int i=0;i<m;++i){ if(i<n)//前n个全部是叶子节点, h1[i].weight=h2[i].weight; else//后面的是还没建成的树 h1[i].weight==0; h1[i].lchild=h1[i].parent=h1[i].rchild=0; } int s1,s2; for(int i=n;i<m;++i){ select(h1,i,s1,s2); h1[s1].parent=i;//建立二叉树 h1[s2].parent=i; h1[i].lchild=s1; h1[i].rchild=s2; h1[i].weight=h1[s1].weight+h1[s2].weight; } str[n]='\0'; int l; for(int i=0;i<n;++i){//从每个叶子节点开始倒序遍历 l=n-1;//倒序赋值字符串 for(int k=i,p=h1[k].parent;p;k=p,p=h1[k].parent){//沿着叶子回溯到根节点 if(k==h1[p].lchild) str[l]='0'; else str[l]='1'; l--; } strcpy(h2[i].code,str+l+1); // printf("%c %s\n",h2[i].data,h2[i].code); }}void EnCodeing(HufCode hc[]){ FILE *f1=fopen("ToBeTran.data","r"); FILE *f2=fopen("Code.txt","w"); char str[maxn]; while(fscanf(f1,"%s",str)!=EOF) { int len=strlen(str); for(int i=0;i<len;++i){ int x=str[i]-'a'; fprintf(f2,"%s",hc[x].code); } fprintf(f2," "); } fclose(f1); fclose(f2);}int Search(HufCode hc[],char *str){ for(int i=0;i<alphanumber;++i) if(strcmp(hc[i].code,str)==0) return i; return -1;}void DeCodeing(HufCode hc[]){ FILE *f1=fopen("CodeFile.data","r"); FILE *f2=fopen("Textfile.txt","w"); char str[maxn]; while(fscanf(f1,"%s",str)!=EOF) { char a[maxn]; memset(a,'\0',sizeof(a)); int len=strlen(str),k=0; for(int i=0;i<len;++i){ a[k]=str[i]; a[k+1]='\0'; int ans=Search(hc,a); if(ans!=-1){ fprintf(f2,"%c",ans+'a'); k=0; continue; } k++; } fprintf(f2," "); } fclose(f1); fclose(f2);}void OutPut(){ FILE *infile=fopen("DataFile.data","r"); FILE *outfile=fopen("Code.txt","r"); int w; char c; printf("各个字母及其权值\n"); for(int i=0;i<alphanumber;++i){ fscanf(infile,"%c %d ",&c,&w); printf("%c %d ",c,w); } infile=fopen("ToBeTran.data","r"); printf("\n\n待编码的内容:\n"); char str[maxn]; while(fscanf(infile,"%s",str)!=EOF) printf("%s ",str); printf("\n编码后结果:\n"); while(fscanf(outfile,"%s",str)!=EOF) printf("%s ",str); printf("\n\n待解码内容:\n"); infile=fopen("CodeFile.data","r"); while(fscanf(infile,"%s",str)!=EOF) printf("%s ",str); printf("\n解码结果:\n"); outfile=fopen("Textfile.txt","r"); while(fscanf(outfile,"%s",str)!=EOF) printf("%s ",str); printf("\n"); fclose(infile); fclose(outfile);}int main(){ HufCode hc[maxn]; HufNode tree[maxn]; Init(hc);//初始化 HuffmanTree(hc,tree,alphanumber);//建树 EnCodeing(hc);//编码 DeCodeing(hc);//解码 OutPut();//输出结果 return 0;}
阅读全文
1 0
- 哈夫曼编/译码系统的设计与实现
- 哈夫曼编/译码的设计与实现
- 简单哈夫曼 编/译码系统的设计与实现
- 哈夫曼编码/译码的设计与实现
- 哈夫曼编/译码演示系统的C程序
- 课程设计哈夫曼编/译码系统
- 二维条形码编码与译码的计算机实现
- 哈夫曼树的编码与译码
- 哈夫曼编译码C语言实现
- 数据结构:哈夫曼树,哈夫曼编码与译码系统
- C语言实现哈夫曼编码与译码
- C语言实现哈夫曼编码与译码
- Huffuman编码与译码C语言实现
- 3G测试系统的Viterbi译码及DSP实现及优化
- 哈夫曼树构建,编码,译码的实现------数据结构
- DES译码程序的MFC实现
- 中小企业办公自动化系统的设计与实现
- WebGIS系统的设计与实现
- Java与算法(13)
- 利用委托在子窗体设置父窗体控件
- windows使用gRPC框架的详细说明
- 简述正则表达式的语法规则(一)
- IDEA 2017.1.4 x64 破解成功
- 哈夫曼编/译码系统的设计与实现
- (spring-mybatis-mysql整合)纯Java配置类配置事务管理
- 解决IDEA调试Hadoop程序中无法加载本地库的问题
- 存储过程和触发器作用以及使用
- 第10篇:ui-router+ocLazyLoad实现控制器js文件的按需加载
- Android之数据库框架greenDAO3.0使用指南
- php中的构造方法和析构方法
- oracel 批量删除 所有表 及 数据
- UVA 12677 Join two kingdoms 题解