zoukankan      html  css  js  c++  java
  • 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
    







  • 相关阅读:
    BZOJ 1101 莫比乌斯函数+分块
    BZOJ 2045 容斥原理
    BZOJ 4636 (动态开节点)线段树
    BZOJ 2005 容斥原理
    BZOJ 2190 欧拉函数
    BZOJ 2818 欧拉函数
    BZOJ 3123 主席树 启发式合并
    812. Largest Triangle Area
    805. Split Array With Same Average
    794. Valid Tic-Tac-Toe State
  • 原文地址:https://www.cnblogs.com/peterzhangsnail/p/12521670.html
Copyright © 2011-2022 走看看