香农法诺算法

时间:2014-10-29 16:06:24

标签: algorithm delphi

我尝试根据示例实现算法:

enter image description here

“Shannon Fano”

根据这个决定,我必须得到A = 11,B = 101,C = 100,D = 00,E = 011,F = 010.但我得到A = 11 B = 101 C = 100 D = 01 E = 001 F = 000 这是我的代码:

Input parametrs: frequencies = [50, 39, 18, 49, 35, 24] и chars =  [A, B, C, D, E, F]
OnClick: SearchTree(' ',' ', 1, charCount,Memo1);


procedure SearchTree(branch:char; full_branch:string; start_pos:integer; end_pos:integer; memo:TMemo);
var
  dS:real; 
  i, m, S:integer; 
  c_branch:string; 
  x,y,j:integer;
begin
  if (branch<>' ') then c_branch := full_branch + branch
  else c_branch := '';

  if (start_pos = end_pos) then
  begin
    memo.Lines.Add(chars[start_pos]+ ' = ' + c_branch);
    exit;
  end;

   x:=0;  y:=0;
   i:=start_pos-1;  j:=end_pos;
   repeat
   Inc(i);
   x:=x+frequencies[i];
   while ((x>=y) and (i<>j))do
     begin
      y:=y+frequencies[j];
      Dec(j);
     end;
     m:=i;
   until (i=j);
  SearchTree('1', c_branch, start_pos, m,memo);
  SearchTree('0', c_branch, m+1, end_pos,memo);
end;

提示我是否理解算法以及我的问题是什么?

1 个答案:

答案 0 :(得分:3)

我不会尝试破译你的代码,但是为了它的价值,你在这里所做的并不是我理解Shannon-Fano编码的方式。

我必须马上承认,我从未亲自编写过一个(选择使用霍夫曼编码,为所有输入数据提供与所有输入数据相同或更好的压缩效果)。

以下是我认为应该根据您的样本数据构建S​​hannon-Fano代码的方法:

给定角色频率:

A   B   C   D   E   F
50, 39, 18, 49, 35, 24 = 215 (ideal distribution = 215 / 2 = 107.5 to each start bit)

现在对频率进行排序:

A   D   B   E   F   C
50, 49, 39, 35, 24, 18 = 215 (ideal distribution = 215 / 2 = 107.5 to each start bit)

现在找到此列表中的分割点,提供最少量的“错误”(浪费):

50 | 49 39 35 24 18 -- error (distance to ideal 107.5) = 57.5 
50 49 | 39 35 24 18  -- error (distance to ideal 107.5) = 8.5
50 49 39 | 35 24 18 -- error (distance to ideal 107.5) = 30.5

因此,第一级的最佳分割点在49(D)和39(B)之间,这反过来意味着我们在左侧分支上有AD,在右侧分支上有BEFC。

由于左侧分支上只剩下两个字符,我们直接编码:

假设left为1且right为零,A变为11,D变为10.

然后所有剩余的字符编码(BEFC)从零开始。

现在,您可以使用相同的方式递归重复此过程,直到列表中最多有两个条目,您就完成了。