今天遇到一个问题,简要来说就是输入一串字符串,对其进行无损压缩,尽量做到压缩原始数据量。最先考虑到的方法是Huffman编码,将其实现过程简要描述。
第一步,输入一串字符串。
clear all;
clc;
%% 输入待处理字符串
text = 'aaaabbbbbbbbbccbbbcccaaaaaaaaaaaaaaaaaabccaab';
fprintf('原文为:\n');
disp(text);
第二步,计算字符串出现的字符个数与每个字符出现的概率。
text_unique = unique(text);
N = length(text_unique);
p = zeros(1,N);
for i = 1:length(text)
for j = 1:N
if(strcmp(text(i), text_unique(j)) == 1)
p(j) = p(j)+1;
break;
end
end
end
p = p/length(text);
第三步,根据概率计算huffman码表。生成原理不具体介绍,请自行百度。
%% 3.huffman码表确定
[code_list, L_av] = Huffman(p);
for i = 1:length(code_list)
Huff_tab{i,1} = strtrim(code_list(i,:));
Huff_tab{i,2} = text_unique(i);
end
fprintf('huffman 码表:\n');
disp(Huff_tab);
主函数Huffman的实现过程为:
function [h,l]=Huffman(p);
%HUFFMAN Huffman code generator
%[h,l]=huffman(p), Huffman code generator returns h the Huffman code matrix,
% and l the average codeword length for a source with probability vector p.
%p=[0.4,0.2,0.2,0.1,0.1];
if length(find(p<0))~=0,
error('Not a prob. vector, negative component(s)')
end
if abs(sum(p)-1)>10e-10,
error('Not a prob. vector, components do not add up to 1')
end
n=length(p);
q=p;
m=zeros(n-1,n);
for i=1:n-1
[q,l]=sort(q);
m(i,:)=[l(1:n-i+1),zeros(1,i-1)];
q=[q(1)+q(2),q(3:n),1];
end
for i=1:n-1
c(i,:)=blanks(n*n);
end
c(n-1,n)='0';
c(n-1,2*n)='1';
for i=2:n-1
c(n-i,1:n-1)=c(n-i+1,n*(find(m(n-i+1,:)==1))...
-(n-2):n*(find(m(n-i+1,:)==1)));
c(n-i,n)='0';
c(n-i,n+1:2*n-1)=c(n-i,1:n-1);
c(n-i,2*n)='1';
for j=1:i-1
c(n-i,(j+1)*n+1:(j+2)*n)=c(n-i+1,...
n*(find(m(n-i+1,:)==j+1)-1)+1:n*find(m(n-i+1,:)==j+1));
end
end
for i=1:n
h(i,1:n)=c(1,n*(find(m(1,:)==i)-1)+1:find(m(1,:)==i)*n);
l1(i)=length(find(abs(h(i,:))~=32));
end
l=sum(p.*l1);
end
第四步,对输入的字符串进行编码。
%% 4.将原文按码表进行编码
enc_stream = [];
for i = 1:length(text)
for j = 1:length(Huff_tab)
if strcmp(text(i),Huff_tab{j,2})
enc_stream = [enc_stream Huff_tab{j,1}];
break;
end
end
end
fprintf('编码结果为:\n');
disp(enc_stream);
第五步,对已编码的二进制序列进行解码。
%% 5. 解压
dec_stream = [];
I = [];
for i = 1:length(enc_stream)
I = [I enc_stream(i)];
for j = 1:length(Huff_tab)
if strncmp(I, Huff_tab{j,1}, length(Huff_tab{j,1}))
dec_stream = [dec_stream, Huff_tab{j, 2}];
I = [];
break;
end
end
end
fprintf('解码结果为:\n');
disp(dec_stream);
处理结果为:
原文为:
aaaabbbbbbbbbccbbbcccaaaaaaaaaaaaaaaaaabccaab
huffman 码表
'1' 'a'
'01' 'b'
'00' 'c'
编码结果为:
111101010101010101010100000101010000001111111111111111110100001101
解码结果为:
aaaabbbbbbbbbccbbbcccaaaaaaaaaaaaaaaaaabccaab
当然,也可以随机生成字符串统计huffman编码的压缩效率~~