matlab用双重循环实现费诺编码

1.      费诺编码原理:(百度百科)

https://baike.baidu.com/item/%E8%B4%B9%E8%AF%BA%E7%BC%96%E7%A0%81/6479275

2.      费诺编码实现的编程方向的选择:递归or循环?

  • 递归方法实现费诺编码

用递归方法实现费诺编码,逻辑思路无疑是最清晰和最好理解的。

function [y]=fano(大小1Xn的概率矩阵B)

           XXXX;     %排序,分组,分配01码等操作

           if(不满足递归返回条件)    %递归返回判断

                    fano(B的子矩阵1);  %以靠前的分组为新参数,调用自身

                    fano(B的子矩阵2);  %以靠后的分组为新参数,调用自身

           end

end

函数基本的逻辑描述:

求分组概率和a,求前i项累加概率,若大于a/2,分配0/1码à对两个新分组再调用自身。

         递归返回条件的讨论:(如何判断某一分支的编码已经完成)

  • 前一次分组后,该分组里只有两个元素:分配0、1码,该分支编码结束。
  • 前一次分组后,该分组里只有一个元素:该分支编码在上一次分组时就已经结束。

递归编程虽然非常简单直观,便于理解,但是非常的吃内存,而且matlab也不赞成递归,无论是直接的,还是间接的。详见:

(https://ww2.mathworks.cn/help/bugfinder/ref/misrac2012rule17.2.html)

  • 如何用循环的方法代替递归实现费诺编码?

        只关注概率行向量里的某一个元素的编码,在编码过程中,对之进行”追踪”,得到其费诺编码。同样的过程,对概率行向量里的每个元素都进行一遍,即可得到所有元素的费诺编码。

3.      用双重循环实现费诺编码的过程及步骤

  • 最外层循环(对每个概率元素都从头进行一次编码)的设计
  1. 用一个while循环解决分组内元素数目大于2的情况
  2. 分组元素数目等于2时,另行处理

     (分组内数目数目等于1时,其编码在上一次分组时已经完成,故而不讨论)


  • 内层循环的设计


4.      不等长的费诺编码的码字存储问题

  • 由于不等长,不能用一个矩阵来存储所有元素的码字
  • 由3可知,每次内层循环会分配一个0/1码,所以码字的存储应该是可以扩展的

解决办法:利用matlab的字符向量元胞数组

  • 每个元胞对应存储一个码字
  • 因为是字符向量,可以进行字符连接操作(和’0’或者’1’连接)
    • 每次层循环,添加一个’0’/’1’的操作流程

1.        将元胞字符向量转化为一般字符向量(cell2mat)

char=cell2mat(C);

2.        对转化后的字符向量执行连接’0’或者’1’的操作

char=[char '0'];或者char=[char '1'];

3.        将操作完成后的一般字符向量重新赋给元胞字符向量

C={char};

程序设计思路:

1.参数A为待编码的概率行向量,B为A的降序排序

2.用数组Z来保存B中各个元素所在分组的元素总数(初始值为B的长度)

3.用M、N记录B中当前正在编码的元素所在的分组的起始和终止位置

4.用空的元胞字符向量数组C存放编码的码字(C的长度等于B的长度)

实现代码:

function y=fano_code(A)
B=fliplr(A);
[m,n]=size(B);
M=1;
N=n;
Z=ones(1,n).*n;

for j=1:n
    C(j)={''};
end

for i=1:n
    while(Z(i)>2)
        a=sum(B(1,M:N),2)/2;
        for K=M:N
            if sum(B(1,M:K),2)>=a
                if i<=K
                    char=cell2mat(C(i));
                    char=[char '0'];
                    C(i)={char};
                    N=K;
                    Z(i)=N-M+1;
                    break;
                else
                    char=cell2mat(C(i));
                    char=[char '1'];
                    C(i)={char};
                    M=K+1;
                    Z(i)=N-M+1;
                    break;
                end
            end
        end
    end
    
    if Z(i)==2
        if i==M
            char=cell2mat(C(i));
            char=[char '0'];
            C(i)={char};
        else
            char=cell2mat(C(i));
            char=[char '1'];
            C(i)={char};
        end
    end
    M=1;
    N=n;
end

celldisp(C);
end







原文地址:https://www.cnblogs.com/peterzhangsnail/p/12521670.html