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; %排序,分组,分配0、1码等操作
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. 用双重循环实现费诺编码的过程及步骤
- 最外层循环(对每个概率元素都从头进行一次编码)的设计
- 用一个while循环解决分组内元素数目大于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
欢迎转载,转载请注明出处
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· .NET Core内存结构体系(Windows环境)底层原理浅谈
· C# 深度学习:对抗生成网络(GAN)训练头像生成模型
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 本地部署DeepSeek后,没有好看的交互界面怎么行!
· 趁着过年的时候手搓了一个低代码框架
· 用 C# 插值字符串处理器写一个 sscanf
· 推荐一个DeepSeek 大模型的免费 API 项目!兼容OpenAI接口!