Huffman對字串進行無失真壓縮示例
阿新 • • 發佈:2019-02-15
今天遇到一個問題,簡要來說就是輸入一串字串,對其進行無失真壓縮,儘量做到壓縮原始資料量。最先考慮到的方法是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編碼的壓縮效率~~