1. 代碼
clear; clc;
str = 'You have to believe in yourself. That is the secret of success.';
%根據字元串str得到符号集symbols,并計算各集合元素的出現機率數組p
len = length(str);
unique_str = unique(str);
unique_len = length(unique_str);
symbols = cell(, unique_len);
p = zeros(, unique_len);
for i = :unique_len
symbols{,i} = unique_str(i);
p(i) = numel(find(str==unique_str(i))) / len;
end
%根據符号集symbols和機率數組p計算Huffman編碼詞典
[dict, avglen] = huffmandict(symbols, p);
%計算平均碼長
code_len = zeros(unique_len, );
for i = :unique_len
code_len(i) = numel(cell2mat(dict(i,)));
end
max_len = max(code_len);
%列印字典表
for i = :unique_len
fprintf('`%s` : ', unique_str(i));
fprintf('%d ', dict{i,});
fprintf('\n');
end
fprintf('平均碼長 : %f\n', sum(p*code_len) );
fprintf('信源熵 : %f\n', sum(p.*(-log2(p))) );
fprintf('編碼效率 : %f\n', /sum(p.*(-log2(p))) );
%計算字元串最終編碼長度
enc_len = ;
for i = :len
enc_len = enc_len + numel(dict{unique_str==str(i),});
end
fprintf('編碼前字元串總長度 : %d\n', numel(str));
fprintf('編碼後字元串二進制總長度 : %d\n', enc_len);
fprintf('編碼後字元串位元組總長度(%d/8) : %d\n', enc_len, ceil(enc_len/));
%列印最終編碼
fprintf('編碼結果 : ');
for i = :len
%fprintf('%s : ', str(i));
fprintf('%d', dict{unique_str==str(i),});
fprintf(' ');
end
fprintf('\n');
2. 輸出結果
` ` :
`.` :
`T` :
`Y` :
`a` :
`b` :
`c` :
`e` :
`f` :
`h` :
`i` :
`l` :
`n` :
`o` :
`r` :
`s` :
`t` :
`u` :
`v` :
`y` :
平均碼長 :
信源熵 :
編碼效率 :
編碼前字元串總長度 :
編碼後字元串二進制總長度 :
編碼後字元串位元組總長度(250/8) :
編碼結果 :
3. 讨論
Huffman編碼存在不唯一的問題。舉個例子,對于字元串
google
進行Huffman編碼可以是如下:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICOyMDO1ETMzIjNyATM2EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
随意翻到有篇論文中探讨了這個問題,提出增加三條限制來使得Huffman編碼唯一化:
1)盡量減少Huffman樹的層次數
2)層次多的放在右分支
3)先出現的現用于構造