正儿八经的数据压缩小课堂——从C++看词典编码之LZW编码

编程入门 行业动态 更新时间:2024-10-08 02:27:37

正儿八经的数据压缩小课堂——从C++看<a href=https://www.elefans.com/category/jswz/34/1761996.html style=词典编码之LZW编码"/>

正儿八经的数据压缩小课堂——从C++看词典编码之LZW编码

正儿八经的数据压缩小课堂——从C++看词典编码之LZW编码

文章目录

  • 正儿八经的数据压缩小课堂——从C++看词典编码之LZW编码
  • 前言
  • 一、词典编码
    • 1 通用编码的概念
    • 2 词典编码的思路
    • 3 词典解码的思路
  • 二、代码注释
    • 2.压缩效率对比
    • 分析:


前言

什么是编码?我们为什么要编码?要理解这个听上去很高大上的玩意儿其实并不困难——
简单地说,编码是人类利用信息对象(比如数据)的统计特性等特性,来尽可能地压缩对象在传输过程中的体量!以此,来实现本来不可能实现的信息传输过程,还可以节约成本!爽!
今天我们要了解的LZW编码,属于编码大家庭中,词典编码的一种。


一、词典编码

1 通用编码的概念

通用编码的实用性更强、范围更广——管你是什么糟心的实际应用情境,我都能统统“通用”!
许多场合无法观察信源的统计特性,或者可观察但统计特性有变化。对这些数据进行压缩编码的技术统称为通用编码技术。

2 词典编码的思路

常见的数据文件,比如文本、图像、视音频、源代码中,通常都含有大量的重复字符。如果用一些简单的代号代替这些字符串,就可以实现压缩!
字符串与代号的对应表,就是词典。
LZW初始会有一个默认的字典,包含了所有256个8bit字符,单个字符的记号就是它自身,用数字表示就是ASCII值。在此基础上,编码过程中加入的新的记号的映射,从256开始,称为扩展表(Extended Dictionary)。↓


不管词典里单个词条中的字符串有多长,最后对应(映射)的都是一个定长的码字!

3 词典解码的思路

LZW编码与LZ77、LZSS等其他传统词典编码的最大区别就在于,这种方法在解码时,解码端会仿照编码端进行编码时的过程,自行生成一本“解码词典”。


重点来了各位,在上图的例子中,当解码进行到259(解码端收到259时),解码端是懵逼的。为什么?当前解码端的字典里还没有编到259这一项!是的,解码端总是比编码端“延后”一步!
那么怎么办呢?不用担心,首先,我们只要逆向思考一下就会知道,什么时候会出现这种情况——那就是在编码端,当一个词条被录入后,它在下一步里马上就被用到!
比如例子里的:

  1. pw1 ab cw1 a 此时aba录入词典,成为259号词条。
  2. pw2 a cw2 b 此时ab在词典里,继续读下一个字符:pw3 ab cw3 a 此时aba也在词典里!刚刚写进去的,所以这时编码端会直接出一个259给解码端!

通过以上进程,这个问题就好办了!在解码端,我们将会知道这个所谓259号的“未知词条”,它作为一个刚建立就马上被用到的词条,它一定是等于(前一个词条+前一个词条的首字符)!

259:aba = 256:ab + a

为啥捏?看我慢慢道来:
——因为“马上被调用”,所以259是衔接在256尾巴后面的,
ab aba
它的(作为词条被首次正式引用时的)头部的首字符
ab (a)ba
等于(作为词条首次出现被编入词典时的,注意,这和上面不一样!)的尾部的最后一个字符,
ab(a) ba
(其实就是这个a从cw1移动到pw2了哈哈)也就是说,259是个回文形式!(1)
——又因为259的建立就是=前一个词条256的整个词条+下一个单字符的码字(不用纠结,新建词条的最后一个码字一定是一个单字符!)(2)
那么由(1)+(2)可得,这条新建的词条259,就等于(前一个词条+前一个词条的首字符)!

简单版:未知词条=前一个传过来的词条+它的首字符,完事儿。

二、代码注释

/** Definition for LZW coding ** vim: ts=4 sw=4 cindent nowrap*/
#include <stdlib.h>
#include <stdio.h>
#include "bitio.h"
#define MAX_CODE 65535
#pragma warning(disable:4996) struct {int suffix;int parent, firstchild, nextsibling;
} dictionary[MAX_CODE+1];int next_code;
int d_stack[MAX_CODE]; // stack for decoding a phrase#define input(f) ((int)BitsInput( f, 16))
#define output(f, x) BitsOutput( f, (unsigned long)(x), 16)int DecodeString( int start, int code);
void InitDictionary( void);void PrintDictionary( void){int n;int count;for( n=256; n<next_code; n++){count = DecodeString( 0, n);printf( "%4d->", n);while( 0<count--) printf("%c", (char

更多推荐

正儿八经的数据压缩小课堂——从C++看词典编码之LZW编码

本文发布于:2024-03-07 08:33:08,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1717342.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:词典   课堂   数据压缩   正儿八经   LZW

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!