超級簡單的資料壓縮演算法—LZW演算法

lotus_ruan發表於2021-09-09

1. 前文回顧

  在中,我們介紹了哈夫曼壓縮演算法(Huffman compression),本文將介紹LZW演算法

  

2. LZW演算法

  這個演算法很簡單,為了方便講述,我們將採用16進位制,寫程式碼的時候在把它轉回2進位制就是了。

  在16進位制下:A:41; B:42; C:43; D:44;......

  從例子入手:

  圖片描述

  壓縮表是邊讀資料邊建立起來的,一開始,壓縮表裡的資料為各個字元對應的十六進位制值,這裡不一一列出,具體可百度26個字母的十六進位制。

  首先從第一個資料開始讀:

  第一個字元為A, A在壓縮表裡已存在,值是41;

  圖片描述

  下一個字元為B,B在壓縮表裡已存在,值是42;

  前一個字元A與這個字元B結合成AB,給它一個值:81;(為什麼是81?因為41~79都被字母用了)

  把AB加到壓縮表裡:

  圖片描述

  下一個字元為R,R在壓縮表裡已存在,值是52;

  前一個字元B與這個字元R結合成BR,給它一個值:82,加到壓縮表中:

  圖片描述

  下一個字元為A,A在壓縮表裡已存在,值是41;

  前一個字元R與這個字元A結合成RA,給它一個值:83,加到壓縮表中:

  如此類推,一直到D那裡:

  圖片描述

  下一個字元為A, A在壓縮表裡已存在,但下下一個字元為B,它們兩組合而成的AB也在壓縮表裡,我們取含字元最多的AB:

  前一個字元D與這個字串的首字元A結合成DA,給它一個值:87,加到壓縮表中:

  圖片描述

  下一個字元為R, R在壓縮表裡已存在,但下下一個字元為A,它們兩組合而成的RA也在壓縮表裡,我們取含字元最多的RA;

  前一個字串AB與這個字串的首字元R結合成ABR,給它一個值:88,加到壓縮表中:

  圖片描述

  下一個字元為B, B在壓縮表裡已存在,但下下一個字元為R,它們兩組合而成的BR也在壓縮表裡,我們取含字元最多的BR;

  前一個字串RA與這個字串的首字元B結合成RAB,給它一個值:89,加到壓縮表中:

  圖片描述

  下一個字元為A, A在壓縮表裡已存在,但下下一個字元為B,它們兩組合而成的BR也在壓縮表裡; 但下下下一個字元為R,它們三組合而成的ABR也在壓縮表裡,我們取含字元最多的ABR;

  前一個字串BR與這個字串的首字元A結合成BRA,給它一個值:8A,加到壓縮表中:

  圖片描述

  下一個字元為A, A在壓縮表裡已存在,值為41;

  前一個字串BRA與這個字元A結合成ABRA,給它一個值:8B,加到壓縮表中:

  圖片描述

  下一個字元為空,說明資料已經壓縮完了,給個值80作為終止標記:

  圖片描述

  壓縮後的資料就是上述的值的組合,壓縮表直接刪除。

  壓縮後的資料S:41425241434144818382884180。

  壓縮的方法講完了,那麼如何解壓呢?

  我們也是邊解壓邊建表:

  現有壓縮資料S:41425241434144818382884180。

  圖片描述

 

  同樣的,一開始,壓縮表裡的資料為各個字元對應的十六進位制值,這裡不一一列出,具體可百度26個字母的十六進位制。

  首先從第一個資料開始讀:

  第一個值為41,對應字元A:

  圖片描述

  下一個資料為42,對應字元B;

  前一個字元A與這個字元B結合成AB,給它一個值:81,加到壓縮表中:

  圖片描述

  下一個資料為52,對應字元R;

  前一個字元B與這個字元R結合成BR,給它一個值:82,加到壓縮表中:

  圖片描述

  如此類推,一直讀到81:

  圖片描述

  下一個資料為81,對應字串AB;

  前一個字元D與這個字串的首字元A結合成DA,給它一個值:87,加到壓縮表中:

  圖片描述

  下一個資料為83,對應字串RA;

  前一個字串AB與這個字串的首字元R結合成ABR,給它一個值:88,加到壓縮表中:

  圖片描述

  如此類推,一直讀到80:

  圖片描述

  下一個資料為80,這是壓縮的終止值,說明解壓完成了,此時,把壓縮表丟掉。

  解壓後得到原資料S:ABRACADABRABRABRA;

  由於我們的壓縮表都是動態生成的,我們省了儲存它的時間和空間。

  解壓和壓縮都介紹完了,這個演算法也就結束了,超級簡單!

  有時候解壓時,會遇到些有趣的情形,如下圖:

  原資料壓縮:

  圖片描述

  解壓時:

  圖片描述

  下一個資料為81,對應字串AB;

  前一個字元B與這個字串的首字元A結合成BA,給它一個值:82,加到壓縮表中:

  圖片描述

  下一個資料為83,嗯?83?83不在壓縮表裡啊,去哪找83?

  容我們冷靜分析一波:

  首先,壓縮表去到了82,下一個資料就是83。因為是83,所以肯定是個字串。(81以上都是我們自己加的字串!)

  假設83對應的字串為X:

  圖片描述

  前一個字串AB與這個字串的首字元X1(假設X是由X1X2X3...XN組成)結合成ABX1,給它一個值:83,加到壓縮表中:

  圖片描述

  即X=ABX1, X1是X的首字元(ABX1的首字元),即X1=A;

  故得知X=ABA:

  圖片描述

  下一個資料是80,解壓完成。解壓後的原資料為ABABABA;

  至此,LZW演算法介紹完畢。

實現程式碼:

  圖片描述

 

作者:

原文出處:https://www.cnblogs.com/mcomco/p/10475329.html  

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/1762/viewspace-2822085/,如需轉載,請註明出處,否則將追究法律責任。

相關文章