如和使用matlab实现香农编码和解码

简介: 如和使用matlab实现香农编码和解码

前言


在网上看了好多 , 都是对香农进行编码的案例 , 却没有 进行解码的操作 , 今天就来补齐这个欠缺


效果截图如下


代码解析


text = '你好';  % 待编码的文本
  • 定义一个字符串类型的变量text,其值为’你好’。
[encoded, decoded, avgCodeLength, efficiency] = shannonCoding(text);
  • 调用函数shannonCoding对文本信息进行编码,并将编码、解码、平均码长和编码效率作为四个返回值保存到变量encoded, decoded, avgCodeLength和efficiency中。
disp('编码结果:');
disp(encoded);
disp('解码结果:');
disp(decoded);
disp('平均码长:');
disp(avgCodeLength);
disp('编码效率:');
disp(efficiency);
  • 打印输出编码结果、解码结果、平均码长和编码效率。
function [encoded, decoded, avgCodeLength, efficiency] = shannonCoding(text)
  • 定义一个名为shannonCoding的函数,输入参数为待编码的文本字符串text。输出参数为编码结果encoded、解码结果decoded、平均码长avgCodeLength和编码效率efficiency。
symbols = unique(text);
freq = zeros(size(symbols));
for i = 1:length(symbols)
    freq(i) = sum(text == symbols(i));
end
freq = freq / numel(text);
  • 对于字符串text中所有不同的字符,使用unique()函数提取出来并存到symbols数组中,然后计算它们在字符串text中的出现频率。具体来说,利用for循环遍历symbols数组中的每一个字符,并计算其在字符串text中出现的次数,最后将频率存储到freq数组中。最后,将freq数组中的每个元素除以总的字符数numel(text),即可得到每个字符的频率。
cumProb = cumsum(freq);
  • 计算符号累计概率(按照符号出现概率从大到小排列)。
codeTable = cell(length(symbols), 2);
for i = 1:length(symbols)
    codeTable{i, 1} = symbols(i);
    codeTable{i, 2} = ''; % 初始化编码为空
end
  • 初始化编码表codeTable,用cell数组表示。codeTable的行数等于symbols中不同字符的个数,每行有两个元素:第一个是字符本身,第二个是该字符的编码(最开始为空字符串)。
codeTable = buildCodeTable(codeTable, cumProb, 1, '');
  • 调用函数buildCodeTable递归地构建Huffman编码表。
encoded = '';
for i = 1:numel(text)
    symbol = text(i);
    index = find(strcmp(codeTable(:, 1), symbol));
    code = codeTable{index, 2};
    encoded = [encoded, code];
end
  • 遍历文本text中的每个字符,找到对应的Huffman编码,最终将所有字符的编码串联起来,存储在变量encoded中。
decoded = '';
code = '';
for i = 1:length(encoded)
    code = [code, encoded(i)];
    index = -1;
    for j = 1:length(codeTable)
        if strcmp(codeTable{j, 2}, code)
            index = j;
            break;
        end
    end
    if index >= 0
        decoded = [decoded, codeTable{index, 1}];
        code = '';
    end
end
  • 解码过程,将encoded按照长度依次取出一部分,逐个检查编码表codeTable中是否有对应的码。如果有,则对应的字符添加到decoded中,并清空code。
codeLengths = cellfun(@length, codeTable(:, 2));
avgCodeLength = sum(codeLengths .* freq);
  • 计算平均码长,将每个字符的编码长度乘以其在文本中的频率,最后相加即可。
efficiency = 1 ./ avgCodeLength;
  • 计算编码效率,用单位1表示所需的二进制位数,所以编码效率是1除以平均码长。这里使用了向量化操作,相当于计算每个码字所需的二进制位数之和再除以总的码字个数。
end
  • 函数定义结束。


完整代码


text = '你好';  % 待编码的文本
[encoded, decoded, avgCodeLength, efficiency] = shannonCoding(text);
disp('编码结果:');
disp(encoded);
disp('解码结果:');
disp(decoded);
disp('平均码长:');
disp(avgCodeLength);
disp('编码效率:');
disp(efficiency);
function [encoded, decoded, avgCodeLength, efficiency] = shannonCoding(text)
    % 计算字符频率
    symbols = unique(text);
    freq = zeros(size(symbols));
    for i = 1:length(symbols)
        freq(i) = sum(text == symbols(i));
    end
    freq = freq / numel(text);
    % 计算累积概率
    cumProb = cumsum(freq);
    % 构建编码表
    codeTable = cell(length(symbols), 2);
    for i = 1:length(symbols)
        codeTable{i, 1} = symbols(i);
        codeTable{i, 2} = ''; % 初始化编码为空
    end
    % 递归构建编码表
    codeTable = buildCodeTable(codeTable, cumProb, 1, '');
    % 编码
    encoded = '';
    for i = 1:numel(text)
        symbol = text(i);
        index = find(strcmp(codeTable(:, 1), symbol));
        code = codeTable{index, 2};
        encoded = [encoded, code];
    end
% 解码
decoded = '';
code = '';
for i = 1:length(encoded)
    code = [code, encoded(i)];
    index = -1;
    for j = 1:length(codeTable)
        if strcmp(codeTable{j, 2}, code)
            index = j;
            break;
        end
    end
    if index >= 0
        decoded = [decoded, codeTable{index, 1}];
        code = '';
    end
end
    % 计算平均码长
    codeLengths = cellfun(@length, codeTable(:, 2));
    avgCodeLength = sum(codeLengths .* freq);
    % 计算编码效率
    efficiency = 1 ./ avgCodeLength;
end
% 递归构建编码表
function codeTable = buildCodeTable(codeTable, cumProb, index, code)
    if index > length(codeTable)
        return;
    end
    if cumProb(index) <= 0.5
        codeTable{index, 2} = [code, '0'+' '];
        codeTable = buildCodeTable(codeTable, cumProb, index+1, [code, '0']);
    else
        codeTable{index, 2} = [code, '1'+' '];
        codeTable = buildCodeTable(codeTable, cumProb, index+1, [code, '1']);
    end
end

完结 撒花

相关文章
|
9月前
|
机器学习/深度学习
信道编码译码及MATLAB仿真(三)
信道编码译码及MATLAB仿真
431 3
|
9月前
|
算法
信道编码译码及MATLAB仿真(二)
信道编码译码及MATLAB仿真
141 3
|
存储 算法 语音技术
基于ACF,AMDF算法的语音编码matlab仿真
基于ACF,AMDF算法的语音编码matlab仿真
基于DCT变换和huffman编码的语音压缩算法matlab仿真
基于DCT变换和huffman编码的语音压缩算法matlab仿真
|
机器学习/深度学习 传感器 算法
【图像压缩】基于霍夫曼+行程+算术编码多种算法得灰色图像无损+有损压缩附Matlab代码
【图像压缩】基于霍夫曼+行程+算术编码多种算法得灰色图像无损+有损压缩附Matlab代码
|
4天前
|
算法 数据安全/隐私保护
基于AutoEncode自编码器的端到端无线通信系统matlab误码率仿真
本项目基于MATLAB 2022a实现自编码器在无线通信系统中的应用,仿真结果无水印。自编码器由编码器和解码器组成,通过最小化重构误差(如MSE)进行训练,采用Adam等优化算法。核心程序包括训练、编码、解码及误码率计算,并通过端到端训练提升系统性能,适应复杂无线环境。
101 65
|
2月前
|
存储 算法 数据安全/隐私保护
基于方块编码的图像压缩matlab仿真,带GUI界面
本项目展示了基于方块编码的图像压缩算法,包括算法运行效果、软件环境(Matlab 2022a)、核心程序及理论概述。算法通过将图像划分为固定大小的方块并进行量化、编码,实现高效压缩,适用于存储和传输大体积图像数据。
|
6月前
|
算法 5G vr&ar
基于1bitDAC的MU-MIMO的非线性预编码算法matlab性能仿真
在现代无线通信中,1-bit DAC的非线性预编码技术应用于MU-MIMO系统,旨在降低成本与能耗。本文采用MATLAB 2022a版本,深入探讨此技术,并通过算法运行效果图展示性能。核心代码支持中文注释与操作指导。理论部分包括信号量化、符号最大化准则,并对比ZF、WF、MRT及ADMM等算法,揭示了在1-bit量化条件下如何优化预编码以提升系统性能。
|
7月前
|
机器学习/深度学习 算法 计算机视觉
通过MATLAB分别对比二进制编码遗传优化算法和实数编码遗传优化算法
摘要: 使用MATLAB2022a对比了二进制编码与实数编码的遗传优化算法,关注最优适应度、平均适应度及运算效率。二进制编码适用于离散问题,解表示为二进制串;实数编码适用于连续问题,直接搜索连续空间。两种编码在初始化、适应度评估、选择、交叉和变异步骤类似,但实数编码可能需更复杂策略避免局部最优。选择编码方式取决于问题特性。
|
8月前
|
缓存 算法
基于机会网络编码(COPE)的卫星网络路由算法matlab仿真
**摘要:** 该程序实现了一个基于机会网络编码(COPE)的卫星网络路由算法,旨在提升无线网络的传输效率和吞吐量。在MATLAB2022a中测试,结果显示了不同数据流个数下的网络吞吐量。算法通过Dijkstra函数寻找路径,计算编码机会(Nab和Nx),并根据编码机会减少传输次数。当有编码机会时,中间节点执行编码和解码操作,优化传输路径。结果以图表形式展示,显示数据流与吞吐量的关系,并保存为`R0.mat`。COPE算法预测和利用编码机会,适应卫星网络的动态特性,提高数据传输的可靠性和效率。

热门文章

最新文章