实验五-LZW编码的MATLAB实现

信息论编码实验3~9连载,更多看专栏。

一、LZW编码原理介绍

LZW(Lempel-Ziv-Welch)编码又称“串表压缩算法”,是 Welch 将 Lempel 和 Ziv 所提出来的无损压缩技术改进后的压缩方法。该算法通过建立一个字符串表,用较短的码字来表示较长的字符串来实现压缩。

举个例子:考虑序列‘abcabcabc’。

  • 假如将每一个字母都用1个字符表示,那么需要传输的数据量为9个字符;
  • 假如使用LZW编码,创建出字典使得‘abc’可以用一个字符表示(因为出现的概率大),则传输的数据量仅为3个字符。

编码基本思想:

  1. 将序列中所有出现一次的单个字符进行编码;
  2. P 为前缀字符(此时为空),C 为当前读取字符(此时为第一个字符);
  3. 判断 PC 是否存在于当前的字典中。若存在,则令 P = PC;若不存在,则将当前的 PC 添加进字典中,再令 P = C
  4. 重复第三步直到最后一个字符。

二、LZW编码实例

考虑序列 ‘abcbcabcabcd’。
初始编码字典为:
在这里插入图片描述
编码步骤为:
在这里插入图片描述
最终得到的扩充字典为:
在这里插入图片描述

三、代码展示及运行结果

根据上述编码基本思想,可以编写出如下代码:

%% 实验五-LZW编码
clear all
clc
%% 主函数
Str_input = input('请输入一串字符:\n','s');
N = length(Str_input);  % 获得输入字符串长度

% 定义初始字典
dic_ini = string({'a','1';'b','2';'c','3';'d','4'});

% 循环走完整个字符串,扩充字典
P = '';     % 初始化P
C = '';     % 初始化C
dic = dic_ini; % 初始化待扩充字典
Out_bits = ''; % 初始化输出码流
for i=1:N   % 循环每一个字符
    Len_dic = size(dic,1);  % 当前字典长度
    C = Str_input(i);
    PC = strcat(P,C);
    for m=1:Len_dic    % 循环判断整个字典是否有当前的PC
        if strcmp(PC, dic(m,1))==1
            P = PC;
            break;
        else if m==Len_dic    % PC不在当前的字典里
                % 更新字典
                dic(Len_dic+1,1) = PC;
                dic(Len_dic+1,2) = num2str(Len_dic+1);
            
                % 找到P在字典的位置,并输出相应码流
                for n=1:Len_dic    % 循环判断整个字典中当前P的位置
                    if strcmp(P, dic(n,1))==1
                    Out_bits = strcat(Out_bits,num2str(n));
                    end
                end
                
                % 更新P
                P = Str_input(i);
            end
        end
    end
end
% 将最后一步的输出码流加上
% 找到P在字典的位置,并输出相应码流
for n=1:Len_dic    % 循环判断整个字典中当前P的位置
    if strcmp(P, dic(n,1))==1
    Out_bits = strcat(Out_bits,num2str(n));
    end
end

% 输出初始字典
fprintf('初始字典:\n');disp(dic_ini);
% 输出LZW编码后的码字流
fprintf('LZW编码后的码字流:\t');disp(Out_bits);
% 输出扩充的字典
fprintf('扩充字典:\n');disp(dic);

假设用户输入待编码序列为第二部分中的 ‘abcbcabcabcd’,输出结果如下:
在这里插入图片描述

根据上面进行验证,可以检验代码的正确性。

四、程序自评价

代码还有一些待改进的地方:

  1. 初始字典的定义:由于实验课上本人偷懒,所以直接定义了‘abcd’四个字母的初始字典(并保证输入序列都是由这四个字母组成的)。实际上要根据输入的序列,依次将所有的单个字母自动进行定义。
  2. 程序精简:也许可以写一个定义初始字典的子函数,和寻找字符在字典中位置的子函数。

代码原创,但因为原理编写参考到了实验课的指导书,假如有什么不对的地方,侵删。

评论 3 您还未登录,请先 登录 后发表或查看评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:游动-白 设计师:我叫白小胖 返回首页

打赏作者

虎慕

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值