m0_52762547 2023-06-07 22:34 采纳率: 100%
浏览 84
已结题

香农解码的代码问题,无法输出解码结果

#请问这段代码为什么无法输出解码的结果
#

text = 'abracadabra';  % 待编码的文本
[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:numel(encoded)
        code = code + encoded(i);
        index = find(strcmp(codeTable(:, 2), code));
        if ~isempty(index)
            symbol = codeTable{index, 1};
            decoded = [decoded, symbol];
            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
```c


#输出结果如下,解码结果那一行无内容输出

```c
编码结果:
00101111001100111001011110
解码结果:
平均码长:
    6.8182    2.7273    1.3636    1.3636    2.7273

编码效率:
    0.1467    0.3667    0.7333    0.7333    0.3667

但是将代码进行一点点改动

 % 解码
    decoded = '';
    code = '';
    for i = 1:numel(encoded)
        code = code + encoded(i);
        index = find(strcmp(codeTable(:, 2), code));
        if ~isempty(index)
            symbol = codeTable{index, 1};
       else//新加入的
            decoded = [decoded, symbol];
            code = '';
        end
    end

解码结果就会输出一串a
求问如何解决

  • 写回答

4条回答 默认 最新

  • 大师兄6668 Python领域新星创作者 2023-06-07 22:53
    关注

    你这个我逐步打印了一下,确定了问题确实在解码环节,解码的算法写的不对。

    codeTable: [['w', '0'], ['l', '00'], ['h', '000'], ['r', '0001'], ['o', '00011'], ['d', '000111'], ['e', '0001111']]
    encoded: 0000001111000000011000011000100000111
    
    

    这是打印出来的字典和编码后的字符,这里是OK的。
    然后你解码的时候,是针对编码的字符挨个取出来去进行判断是否和字典中的编码一样,这里就要注意了,
    由于每个字母编码时候的字典位数并不相等,但是你取编码字符的时候是逐个取的,然后和它进行比较判断的,一旦字典中的位数不是1,那你解码就会失败,就会变成空白。
    并且,你这个同一个字符串,每次运行的时候,生成的字典是不同的,所以每次解码出来的结果也不一样,但是都有一个特点就是,最多只能解码出来一个字母,或者这个字母的重复
    需要修改你的解码逻辑方可解决,但是位数不一样,不太好改,我正在研究。
    如果可以的话,可以连编码带解码一并修改,这样比较好弄。
    盼回复,一起交流。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 6月16日
  • 已采纳回答 6月8日
  • 创建了问题 6月7日

悬赏问题

  • ¥15 Qt4代码实现下面的界面
  • ¥15 prism提示我reinstall prism 如何解决
  • ¥15 asp.core 权限控制怎么做,需要控制到每个方法
  • ¥20 while循环中OLED显示中断中的数据不正确
  • ¥15 这个视频里的stm32f4代码是怎么写的
  • ¥15 JNA调用DLL报堆栈溢出错误(0xC00000FD)
  • ¥15 请教SGeMs软件的使用
  • ¥15 自己用vb.net编写了一个dll文件,如何只给授权的用户使用这个dll文件进行打包编译,未授权用户不能进行打包编译操作?
  • ¥50 深度学习运行代码直接中断
  • ¥20 需要完整的共散射点成像代码