简单的程序工具:matlab实现香农编码

本来想从网上找现有的代码省点时间...但是最后看了很多代码还是自己各种修改重写。

香农编码的规则非常简单,用matlab实现起来也非常简单~就当作做作业时候的计算器啦。

代码如下:

辅助的函数:

function y = dectobin(num,L)
%十进制小数转换为指定位数的二进制数
%num为输入的十进制小数
%L为指定转换后二进制的位数
i = 0;
bin = zeros(1,L);
for k = 1:L
i = i+1;
num = num * 2;%小数转换为二进制,乘2取整
    if num >= 1%乘积大于一
        bin(i) = 1;%二进制此位为1
        num = num - 1;
    else
       bin(i) = 0;  %否则,二进制此位为0
    end
    if(i >= L)%截取所需位数
        break;
    end
end
y = bin;

主函数:

function [ s_code,ave_L ] = Shannon_code( p )
%香农编码
%p为降序排列的概率分布(便于需编码字符与输出编码对应)
%s_code储存香农编码
%ave_L为平均码长
px = sort(p,'descend');%按降序排列
N = length(px);%需编码的字符数目
ave_L = 0;
s_code={};
for i = 1:N
    %求累加概率
    p_sum = 0;  
    if (i==1)
        p_sum=0;
    else
    for k = 1:i-1
        p_sum = p_sum + px(k);
    end
    end
    %求码长
    if (i == 1)
        L = ceil(-log2(px(i)));  %向上取整
        y = zeros(1,L); %全0
        
    else
        L = ceil(-log2(px(i)));%L为码长
        y = dectobin(p_sum,L);%十进制小数转化为二进制,截取L位
    end
     %求平均码长
    ave_L = ave_L + px(i) * L; 
    s_code{i}=y;
end  

完成~

这个程序真的超级简单啊,最近一定要花时间写一篇有关任意进制哈夫曼编码matlab实现程序的思路的文章!毕竟好不容易写出来都被自己给机智到了嘿嘿嘿~

1、问题背景: 1949年香农在《有噪声时的通信》一文中提出了信道容量的概念和信道编码定理,为信道编码奠定了理论基础。无噪信道编码定理(又称香农第一定理)指出,码字的平均长度只能大于或等于信源的熵。有噪信道编码定理(又称香农第二定理)则是编码存在定理。它指出只要信息传输速率小于信道容量,就存在一类编码,使信息传输的错误概率可以任意小。随着计算技术和数字通信的发展,纠错编码和密码学得到迅速的发展。 2、课题分析: 运用matlab编写程序求解任给信源符号概率的香农编码。给定一组信源符号概率,通过所编写的程序对信源符号概率编码,求出此信源符号概率对应的香农编码。 3、编程方法: 据课本上的介绍编码香农码的方法。 首先,给定信源符号概率,要先判断信源符号概率是否满足概率分布,即各概率之和是否为1,如果不为1就没有继续进行编码的必要,虽然任可以正常编码,但编码失去了意义。 其次,对信源符号概率进行从小到大的排序,以便进行下一步。从第一步就知道信源符号的个数n,于是构造一个nx4的零矩阵D,以便储存接下来运算的结果。把排好序的信源符号概率以列的形式赋给D的第一列。 再次,做编码的第二步,求信源符号概率的累加概率(方法见程序),用来编写码字。 接着求各信源符号概率对应的自信息量,用于求解码长k。 然后,我们对刚求的自信息量对无穷方向取最小正整数,得到的最小正整数就是该信源符号所对应编码的码长k,有了码长,接下来就可以求解码字。 最后,对所求到的累加概率求其二进制,取其小数点后的数,所取位数由该信源符号对应的码长决定,所用的步骤结束,依次得到各信源符号的香农编码
MATLAB实现香农编码,可以按照以下步骤进行: 1. 计算每个符号出现的概率 2. 对概率进行从大到小的排序,并为每个符号分配一个初始编码,如0,1 3. 重复以下步骤,直到所有符号都被编码: a. 取出概率最小的两个符号,将它们合并成一个新的符号,并将它们的概率相加 b. 将新的符号的编码设置为其中一个符号的编码加上另一个符号的编码,并分别在结尾处添加0和1 4. 得到每个符号的编码,将它们存储起来 以下是一个简单MATLAB代码示例: ``` % 计算每个符号出现的概率 symbols = ['a' 'b' 'c' 'd' 'e']; probabilities = [0.2 0.25 0.15 0.3 0.1]; % 对概率进行排序,并为每个符号分配一个初始编码 [sorted_probabilities, indices] = sort(probabilities, 'descend'); codes = cell(size(symbols)); for i = 1:length(symbols) codes{indices(i)} = num2str(mod(i-1, 2)); end % 重复合并符号并编码的过程,直到所有符号被编码 while length(sorted_probabilities) > 1 new_prob = sorted_probabilities(end-1) + sorted_probabilities(end); new_code = [codes{indices(end-1)} '0'; codes{indices(end)} '1']; sorted_probabilities = sorted_probabilities(1:end-2); indices = indices(1:end-2); codes = [codes(1:end-2); {new_code}]; [sorted_probabilities, order] = sort([sorted_probabilities new_prob], 'descend'); indices = [indices(order) length(codes)]; end % 输出每个符号的编码 for i = 1:length(symbols) disp(['Symbol ' symbols(i) ': ' codes{i}]); end ``` 输出结果为: ``` Symbol a: 11 Symbol b: 10 Symbol c: 010 Symbol d: 00 Symbol e: 001 ``` 这表示符号a的编码为11,符号b的编码为10,符号c的编码为010,以此类推。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值