当前位置:文档之家› 信息论实验用matlab实现哈夫曼码编译码

信息论实验用matlab实现哈夫曼码编译码

信息论与编码基础课程实验报告实验名称:Huffman码编译码实验姓名:学号:组别:专业:指导教师:班队:完成时间:成绩:Huffman码编译码实验一.实验目的和要求熟悉matlab软件编程环境及工具箱,掌握Huffman码编译码方法的基本步骤,利用matlab实现Huffman码的编译码。

二.试验内容和原理内容:利用matlab编程实现文本的二进制Huffman码的编译码。

任务:构造Huffman树。

原理:在各字符出现概率不均匀的情况下,根据这些概率构造一棵用于编码的Huffman树。

它用最短的二进制位表示出现概率最高的字符,而用较长的为表示出现概率低的字符,从而使平均码长缩短,并且保持编码的唯一可译性。

三.操作方法和实验步骤对一随机英文文本文件进行Huffman编译码仿真,给出各个字母的概率,码字,平均信息量,平均码长,编码效率以及编码序列输出。

(一)编码序列获取使用fopen函数读取.txt文本文件中的数据存储为字符串,使用length获取其长度,使用unique获取字符个数。

(二)获取编码概率矩阵使用strfind函数获取字符个数并计算各个符号的概率,根据哈夫曼编码原理依次获得各步骤中得到的概率,赋值给概率矩阵,使用find查找合并概率在的下标并存储到该列的最后一位,如有两个以上优先存储较大的那个下标。

(三)获取编码矩阵依据哈夫曼编码原理,根据获取的概率矩阵倒序编码。

最后一列直接编码0和1,取出最后一行中记录合并概率下标的数,由于该合并概率在上一列中肯定在最后两行,故优先编码,在字符串尾部加0和1;剩余编码直接平移,使用if 条件控制由于合并概率位置不同带来的平移方法不同。

(四)计算平均码长、自信息等使用公式计算平均码长、自信息、编码效率平均码长自信息编码效率(五)依据编码表编码由于是单符号信源,故使用strrep 字符替换函数直接替换(六)反向译码哈夫曼码是前向译码,遍历编码表,使用strncmpi 比较传输信息前x 个字符,如返回值为真直接译码,传输信息截取已经译码的部分,码字添加到译码信息中。

四.实验数据记录和处理close all ;clear all ;clc;%关闭所有图形窗口,清楚工作空间所有变量,清除命令行%%%%%%%%%文件数据读取%%%%%%%%%%code=fopen( '\test02.txt'); %打开文件mail=fscanf(code, '%c'); %读取文件的数据,并将数据存入矩阵,输出字符串 mms=unique(mail); %unique 函数去除重复字符,计算出字符串的种类 % disp(xulie); %输出文档中包含的字符n=length(mms); %n 为需要编码元素个数,length 函数获取字符串长度 for i=1:ncount(i)=length(strfind(mail,mms(i)));rLS 2log /)(H =η符号码元/l p L q1i i i ∑==码元/bit p log p H(S)q1i i 2i ∑=-=%统计各字符个数复制给count(i),strfind为字符查找函数,返回值为查找个数endP=count./sum(count); %计算各字符的概率for i=1:nPP{i,1}=mms(i);PP{i,2}=P(i);endPP=sortrows(PP,-2);T=sort(P,'descend'); %降序排列P,为减少对P的影响,复制排序后的P为T %%%%%%%%%%%%%编码准备(概率矩阵生成)%%%%%%%%%%B=zeros(n,n-1);%B为空的编码概率矩阵,第一列n个,最后一列2个故用n*(n-1)for i=1:nB(i,1)=T(i); %生成编码表的第一列(即为复制T)endr=B(i,1)+B(i-1,1); %最后两个元素相加T(n-1)=r; %将两个元素相加之和赋给倒数第二个数T(n)=0; %最后一个数置零T=sort(T,'descend'); %对第一次相加后的T排序t=n-1; %置数t,用来表示当前概率序列中不为零的个数for j=2:n-1 %生成编码表的其他各列(从第二列开始)for i=1:tB(i,j)=T(i); %将上一次处理后的概率序列复制给下一列endK=find(T==r);%找到r在T中的位置并置给K(K是向量,记录的是位置信息所在列数)B(n,j)=K(1);%从第二列开始,每列的最后一个元素记录上一列相加后的数在该列的位置,取概率之首可以减少码长方差r=(B(t-1,j)+B(t,j)); %最后(小)两个概率相加T(t-1)=r;T(t)=0; %重复动作,相加最小两数,并将后一位置零T=sort(T,'descend'); %对T再排序t=t-1; %每次处理后t自减(需处理的概率自减)end%%%%%%%%%%%%%%编码部分%%%%%%%%%%%%%%%m=n-1; %为简便引入m,表示码字最长可能,也是列数等huffman{1,m}='0';huffman{2,m}='1';t=2; %t是实时本列的概率元素个数,也表示下一列第一个合并概率的行数for j=m:-1:2 %j是实时的列数k=B(n,j);huffman{t,j-1}=strcat(huffman{k,j},'0'); %先解决上一列最后两个huffman{t+1,j-1}=strcat(huffman{k,j},'1');%strcat做字符串拼接if k==1 %如果合成的概率排在首位,那就斜着复制for i=1:t-1 %i表示列数,z表示字符顺序huffman{i,j-1}=huffman{i+1,j};endelseif k==t %如果合成的概率排在末位,那就平着复制for i=1:t-1huffman{i,j-1}=huffman{i,j};endelse%如果合成的概率排在中间,上半部分平着,下半部分斜着for i=1:k-1 %上半部分平移huffman{i,j-1}=huffman{i,j};endfor i=k:t-1 %下半部分斜着移过去huffman{i,j-1}=huffman{i+1,j};endendt=t+1;endhuffman%%%%%%%%%输出结果%%%%%%%%%%%%%%disp('编码结果')for i=1:nPP{i,3}=huffman{i,1};endPP=sortrows(PP,-2); %sortrows对字符依据概率大小排序disp(PP); %输出for i=1:nlong=length(PP{i,3});L(i)=long;enddisp('平均码字长度');len=sum(L.*P);disp(len); %平均码长lenH1=log2(P);disp('平均信息量');H=-P*(H1'); %平均信息量Hdisp(H);disp('编码效率');Pp=H/len; %编码效率Ppdisp(Pp)%%%%%%%%%%%%%%%编码部分%%%%%%%%%%%%%%%%%tran=strrep(mail,char(PP{1,1}),char(PP{1,3})); %strrep为字符替换函数for i=2:ntran=strrep(tran,char(PP{i,1}),char(PP{i,3}));enddisp('编码输出')disp(tran);%%%%%%%%%%%%%%%%译码部分%%%%%%%%%%%%%%%%%%retran='';left=tran;%比较传输字符的前几位与码字,如果找到将译码部分添加到retran,剩余数据截取存储到leftwhile(length(left)>0)for i=1:nif (strncmpi(left,char(PP{i,3}),length(PP{i,3})))retran=strcat(retran,char(PP{i,1}));left=left((length(PP{i,3})+1):length(left));endendenddisp('译码输出')disp(retran);disp('原始信息')disp(mail);if(strcmp(mail,retran))disp('译码成功');end五.实验结果与分析1.(1)测试文件test01.txt中存储字符串(2)查看概率矩阵B(3)查看编码矩阵huffman (4)查看运行结果,编译码无误2.(1)测试文件test02.txt中存储字符串(2)查看概率矩阵B(3)查看编码矩阵huffman(4)查看运行结果,编译码无误3.结果分析可知,程序已完成了Huffman编码的功能,但结果并不唯一,验证了霍夫曼编码是不唯一的。

因为:信源符号合并中遇到最小概率相同的情况时可任意选择来做合并;在码树分配编码码字的时候1 和0 的位置可以是任意的。

编码本码字不同并不影响文本传输,六.讨论和心得思考:1、如何对文本进行概率统计?答:读取文本数据存储在字符串中,使用unique去除重复字符得到字符集合,遍历字符串,得到各个字符的个数。

2、如何分析编码性能?答:平均码长、编码效率都是直接反映编码性能的参数。

哈夫曼码的平均码长比相同信源的香农码和费诺码短;编码效率为编码后信息传输速率与最大可能信息传输速率的比值。

3、试分析Huffman码在使用中的复杂性、并行性的相应改进。

(选答)答:哈夫曼码在编码过程中需要重复排序,编码过程比香农编码和费诺编码复杂,使用过程中不等长编码和等长编码在译码过程中更复杂。

相关主题