代码
n=app.NEditField.Value;
%A_str=split(app.PEditField_5.Value,',');%p的值顺序与app输入框顺序相反
A=app.PEditField_5.Value;
A=str2num(A);
%if sum(A)~=1
%disp('不符合概率分布')
% else A=fliplr(sort(A));%按降序排列
A=sort(A,'descend');%按降序排列
T=A;u=A;
A=A/sum(A);
[~,n]=size(A);
%生成待编码矩阵,每列最后一个元素为特殊元素的位置
B=zeros(n,n);
for i=1:n
B(i,1)=T(i);%生成编码表的第一列
end
r=B(i,1)+B(i-1,1);%最后两个元素相加
T(n-1)=r;T(n)=0;
T=sort(T,'descend');
t=n-1;
for j=2:n%生成编码表的其他各列
for i=1:t
B(i,j)=T(i);
end
if t>1
K=find(T==r);
B(n,j)=K(end);%从第二列开始,每列的最后一个元素记录特征元素在该列的位置
r=(B(t-1,j)+B(t,j));%最后两个元素相加
T(t-1)=r;
T(t)=0;
T=sort(T,'descend');
t=t-1;
else
B(n,j)=1;
end
end
%生成Huffman码字矩阵和排序后元素的码表向量
m=3;s1=str2sym('[2,1]');s2=s1;%码表,用1表示0,2表示1,因为0会因为被省略导致无法记录
%这里意思是从倒数第三列开始建表,因为最后一列和倒数第二列的情况我们可以直接推出。
for i=n-2:-1:1
p=B(n,i+1);%p是每列保存的特殊元素的位置,特殊元素指的是由上一列最后两个数新合成的数
if p==1
s2(1:m-2)=s1(2:m-1);
elseif p==m
s2(1:m-2)=s1(1:m-2);
elseif p==2
s2(1)=s1(1);
s2(2:m-2)=s1(3:m-1);
else
s2(1:p-1)=s1(1:p-1);
s2(p+1:m-2)=s1(p+1:m-2);
end
s2(m-1)=[char(s1(p)),'2'];
s2(m)=[char(s1(p)),'1'];
m=m+1;
s1=s2;
end
L=zeros(1,n);
for i=1:n
[~,r]=size(char(s2(i)));
L(i)=r;
end
%将码表转换成0和1输出
arr=zeros(1,n);
arr(1:n)=s2(1:n);
str=[];
for i=1:n
s=num2str(arr(i));
s=strrep(s,'1','0');
s=strrep(s,'2','1');
if i==1
str=s;
else
str=[str,' ',s];
end
end
str=regexp(str,' ','split');
%计算返回值
c=str;
e=sum(L.*A);%平均码长
H1=log2(A);
H=-A*(H1');%熵
f=H/e;%编码效率
%avlen=sum(L.*A);%平均码长
app.IEditField.Value= string(e); % 输出平均码长
app.HEditField.Value=string(H); %输出信源熵
%P=H/avlen;%编码效率
app.EditField_12.Value=string(f); %输出编码效率
app.TextArea_2.Value=c;
end
输入输出效果
![在这里插入图片描述](https://img-blog.csdnimg.cn/59fe03d2e58b4a678408fd011538c927.jpeg)