**************主函数:************************
%Huffman编码
clear;clc;close all;
[word,prob]=statistics(); %对文本中的信息进行统计
huff=Code(prob); %编码
for i=1:length(prob)
len(i)=length(find(abs(huff(i,:))~=32));
%检测编码长度并进行标记
end
ave=sum(prob*len') %计算平均码长
HX=sum(prob.*(-log2(prob))) %计算信源熵
efficiency=HX/ave %计算编码效率
r=1-efficiency %计算冗余度
————————————————
版权声明:本文为CSDN博主「路遇春山」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_56647551/article/details/127752235
编码主函数
输入文本文件xx.txt
*****************字符统计************************
function [word,prob] = statistics() %统计文档中信源及个数
data=textread('D:\desktop\Huffman\xx.txt','%s', 'whitespace','');
x=cell2mat(data);
x=x';
tab=tabulate(x);
w=char(tab(:,1)); %字符表
dimension=size(w);
word(1:dimension(1),1)=char(tab(:,1));
word(dimension(1)+1,1)=' ';
for i=1:dimension(1)+1
count(i)=length(find(x==word(i)));
end
prob=count/sum(count); %各字符的概率
end
————————————————
版权声明:本文为CSDN博主「路遇春山」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_56647551/article/details/127752235
*********************编码函数code()*********************
function huff = Code(prob)
%进行Huffman编码
n=length(prob);
p=prob
loca=zeros(n-1,n);
%loca用于记录每行最小两概率叠加后概率的排列次序
for i=1:n-1
[p,index]=sort(p) %进行概率值排序
loca(i,:)=[index(1:n-i+1),zeros(1,i-1)] %每一次排序求和后都会少一个概率值,对有值的赋予排列次序,其余赋0
p=[p(1)+p(2),p(3:n),1] %对经过求和处理的概率第一项赋两最小概率的和值,对3-n项概率照搬,其余概率赋1
end
for i=1:n-1 %循环生成一个N-1行、n^2列数组C,每行可看作n个段,每段长为n,记录一个码字(每个码字的长度不会超过n)
code(i,1:n*n)=blanks(n*n)
end
code(n-1,n)='0' % 给code矩阵的N-1行的第一个段赋值0
code(n-1,2*n)='1' % 第二个段赋值1。(这两个码字对应编码中最后相加为一的两个概率)
for i=2:n-1 %主要的程序,循环N-2次
code(n-i,1:n-1)=code(n-i+1,n*(find(loca(n-i+1,:)==1))-(n-2):n*(find(loca(n-i+1,:)==1)))
code(n-i,n)='0' %在分支的第一个元素最后补0
code(n-i,n+1:2*n-1)=code(n-i,1:n-1)
code(n-i,2*n)='1' %在分支的第一个元素最后补1
%每一行值都从下一行值得到,找到在下一行码字中相加本行最小两个概率得到的概率的对应码字,
%本行两个最小概率对应码字分别为此码字最后加“0”,加“1”
for j=1:i-1
code(n-i,(j+1)*n+1:(j+2)*n)=code(n-i+1,n*(find(loca(n-i+1,:)==j+1)-1)+1:n*find(loca(n-i+1,:)==j+1))
end
end
for i=1:n
huff(i,1:n)=code(1,(find(loca(1,:)==i)-1)*n+1:find(loca(1,:)==i)*n)
end
end
————————————————
版权声明:本文为CSDN博主「路遇春山」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_56647551/article/details/127752235
********************* 输出码书**********************
fid=fopen('codeBook.txt','w+');
for i=1:length(prob)
fprintf(fid,'%s',word(i));
for j=1:length(word)
fprintf(fid,'%s',huff(i,j));
end
fprintf(fid,'\n');
end
fclose(fid);
————————————————
版权声明:本文为CSDN博主「路遇春山」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_56647551/article/details/127752235
输出码书
*********************输出二进制比特流**************************
huffcode=[];
for i=1:length(x)
temp=huff(find(word==x(i)),:); %temp存放当前字符对应的Huffman编码
loc=find(abs(temp)~=32); %找到不是空格的第一个0或者1
new=temp(loc(1):length(word)); %取出码字
huffcode=[huffcode,new] %拼接码字
end
fid=fopen('codeFile.txt','w+');
fprintf(fid,'%s\n',huffcode);
fclose(fid);
****************输出每个码字码长********************
lenth=[];
for i=1:length(x)
lenth=[lenth,len(find(word==x(i)))];
end
fid=fopen('Length.txt','w+');
for i=1:length(lenth)
fprintf(fid,'%d',lenth(i));
end
fclose(fid);
————————————————
版权声明:本文为CSDN博主「路遇春山」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_56647551/article/details/127752235
编码结果
计算压缩效率:
读入codeFile.txt,编写霍夫曼编码的译码程序,进行译码,验证编码正确性。
***************Huffman译码********************
%Huffman译码
clear;clc;close all;
code=textread('codeFile.txt','%c');
book=textread('codeBook.txt','%s');
n=length(book);
book(n+1)=book(n);
% book(n)=cellstr(' ');
word_code=zeros((n+1)/2,(n+1)/2);
word_code=char(word_code);
for i=1:(n+1)/2
word_code(i,:)=blanks((n+1)/2);
end
%存放字符字典
for i=1:(n-1)/2
word(i)=cell2mat(book(2*(i-1)+1));
end
word((n+1)/2)=' ';
for i=1:(n+1)/2 %存放字符码字字典
word_code(i,1:length(cell2mat(book((2*i)))))=cell2mat(book((2*i)));
end
%开始译码
for i=1:(n+1)/2 %计算每个码字的长度
temp=find(word_code(i,:)==32);
len(i)=temp(1)-1;
end
unit=[]
decoding=[]
for i=1:length(code)
unit=[unit,code(i)]
for j=1:(n+1)/2
if length(unit)==len(j)
if double(sum(unit==word_code(j,1:len(j))))==length(unit)
decoding=[decoding,word(j)]
unit=[]
end
end
end
end
%输出译码结果
fid=fopen('Decode.txt','w+');
fprintf(fid,'%s\n',decoding);
fclose(fid);
————————————————
版权声明:本文为CSDN博主「路遇春山」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_56647551/article/details/127752235
译码代码如上
译码结果与原文本一致
接下来设计交互界面(使用MATLAB自带的Appdesigner)
在输入栏中输入所需编码的文本文件名,点击Button对.txt文件所在文件夹进行选择,即可对文件进行霍夫曼编码,码书显示于表格,编码结果(2进制比特流)保存于同一文件夹下的’AppCode.txt’。
function ButtonPushed(app, event)
clc;
srcDir=uigetdir('','选择需要进行编码的文本');
loc=app.EditField_2.Value;
location=fullfile(srcDir,[loc]);
[word,prob]=statistics_App(location); %对文本中的信息进行统计
huff=Code(prob); %编码
chuff=cellstr(huff);
cword=cellstr(word);
xlswrite('D:\desktop\MATLAB\zyh\Huffman\Book.xlsx',[cword,chuff]);
t=readtable('Book.xlsx');
app.UITable.Data=[cword,chuff];
s = uistyle('HorizontalAlignment','center');
addStyle(app.UITable,s,'table','');
data=textread(location,'%s', 'whitespace','');
x=cell2mat(data);
huffcode=[];
for i=1:length(x)
temp=huff(find(word==x(i)),:); %temp存放当前字符对应的Huffman编码
loc=find(abs(temp)~=32); %找到不是空格的第一个0或者1
new=temp(loc(1):length(word)); %取出码字
huffcode=[huffcode,new] %拼接码字
end
fid=fopen('AppCode.txt','w+');
fprintf(fid,'%s\n',huffcode);
fclose(fid);
end
end
————————————————
版权声明:本文为CSDN博主「路遇春山」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_56647551/article/details/127752235
回调函数如上
输出比特流展示