0


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

文章目录

前言

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

效果截图如下

在这里插入图片描述

代码解析

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

完整代码

  1. 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)% 计算字符频率
  2. symbols =unique(text);
  3. freq =zeros(size(symbols));fori=1:length(symbols)freq(i)=sum(text ==symbols(i));end
  4. freq = freq /numel(text);% 计算累积概率
  5. cumProb =cumsum(freq);% 构建编码表
  6. codeTable =cell(length(symbols),2);fori=1:length(symbols)
  7. codeTable{i,1}=symbols(i);
  8. codeTable{i,2}='';% 初始化编码为空end% 递归构建编码表
  9. codeTable =buildCodeTable(codeTable, cumProb,1,'');% 编码
  10. encoded ='';fori=1:numel(text)
  11. symbol =text(i);
  12. index =find(strcmp(codeTable(:,1), symbol));
  13. code = codeTable{index,2};
  14. encoded =[encoded, code];end% 解码
  15. decoded ='';
  16. code ='';fori=1:length(encoded)
  17. code =[code,encoded(i)];
  18. index =-1;forj=1:length(codeTable)ifstrcmp(codeTable{j,2}, code)
  19. index =j;break;endendif index >=0
  20. decoded =[decoded, codeTable{index,1}];
  21. code ='';endend% 计算平均码长
  22. codeLengths =cellfun(@length,codeTable(:,2));
  23. avgCodeLength =sum(codeLengths .* freq);% 计算编码效率
  24. efficiency =1./ avgCodeLength;end% 递归构建编码表function codeTable =buildCodeTable(codeTable, cumProb, index, code)if index >length(codeTable)return;endifcumProb(index)<=0.5
  25. codeTable{index,2}=[code,'0'+' '];
  26. codeTable =buildCodeTable(codeTable, cumProb, index+1,[code,'0']);else
  27. codeTable{index,2}=[code,'1'+' '];
  28. codeTable =buildCodeTable(codeTable, cumProb, index+1,[code,'1']);endend

完结 撒花


本文转载自: https://blog.csdn.net/qq_33681891/article/details/131105724
版权归原作者 全栈若城 所有, 如有侵权,请联系我们删除。

“如和使用matlab实现香农编码和解码”的评论:

还没有评论