LZW編碼的學習與實現

2021-08-03 09:24:31 字數 3493 閱讀 6159

**

目錄(?)

[+]

preface

encoding

基本思想

流程**實現

decoding

主要思想

流程**實現

看了一天,感覺終於搞明白了一點(**終於寫對了),編碼過程大四的時候學過一點點,按部就班的按照步驟來做就行了,解碼過程貌似課堂上老師沒講,自己看wiki上的講解和example搞懂了。

lzw全稱lempel–ziv–welch,就是這個三個人搞出來的。

lzw的工作思路,考慮一段資料,abcabcabc,對於這樣的一段資料,如果不做任何處理和壓縮,假設每個字元用乙個位元組來表示,直接儲存的空間應該是9位元組。詳細說明下:

下表是我們dictionary,也就是碼表,字元與編碼的對應。

character

decimal

binarya1

0000 0001b2

0000 0010c3

0000 0011

觀察上面的字串,發現abc是重複的,如果abc能用乙個位元組來表示的話,那麼,只需要3位元組儲存就足夠了。

character

decimal

binary

abc1

0000 0001

ok,lzw就是這個尿性,它就是想這麼搞。

編碼的基本思想是這樣的,首先我們有乙個碼表或者稱為dictionary,裡面只定義單個字元和編碼,比如0-9a-za-z這些,其實ascii碼中的所有全部都放進去都可以。

也就是說通常用十進位制數0-255來表示單一字元(single character)。

然後我們開始讀取字串,很顯然對於任何常規字串,每個single character都可以得到乙個碼字,但是如果我們不做處理的話,那麼n個字元encode後,就是n個碼字了完全沒有壓縮。

所以,再邊讀取的時候,一邊開始對dictionary進行擴增,不斷的將single character拼接成dictionary中不存在的符號(symbol),擴充dictionary,這樣下次再次遇到這樣的組合,就可以使用有乙個碼字表示了。

說實話,用純文字描述還真的不是很好描述,於是我畫了乙個流程圖來描述這樣乙個過程。

就是上面這個圖了,**只要照著這個寫就能搞定問題。但出於尊重,還是要講解下比較好。

首先我們需要兩個暫存器,p和c,為啥叫這個名字呢。(當時上學那會,老師給的是p和s,完全不知道意義)

p -> previous -> 表示之前的字元

c -> current -> 表示當前讀取的字元

然後我們考慮字串abcbcabcabcd來,按步驟演算一下:

首先我們需要乙個dictionary,簡單考慮,只考慮a-d,4個英文小寫字母吧。

symbol

decimala1

b2c3

d4下面是演算過程:

steppc

is pc in dic

output p

dictionary

description

1null

a初始化,不處理2a

bno1ab:5

ab不存在dictionary中,擴充3b

cno2bc:64c

bno3cb:75b

cyes

bc在dictionary中,p = pc6bc

ano6bca:87a

byes8ab

cno5abc:99c

ano3ca:1010a

byes

11ab

cyes

12abcdno

913dnull4結束

經過上面的演算過程,我們的dictionary也擴充套件為:

symbol

decimala1

b2c3

d4ab5

bc6cb7

bca8

abc9

ca10

最後貼下自己實現的**:

public

static listencode(string data)

string previous = "";

string pc = "";

for (char c : data.tochararray()) else

}//最後一次輸出

if (!previous.equals(""))

return result;

}

output

//abcbcabcabcd

[97, 98, 99, 257, 256, 99, 260, 100]

解碼的主要思想是,乙個編碼序列,我們也是事先知道乙個固定的碼表,我一邊讀取碼字,一邊輸出解碼後的字元,同時一邊擴充碼表。這個我也覺得好難用用文字表達清楚,上流程圖。

同樣的,這裡給出乙個編碼序列

[97, 98, 99, 257, 256, 99, 260, 100]
首先我們需要乙個預設的dictionary。

decimal

symbol97a

98b99c

100d

接下來是演算過程:

inputpc

is c in dic

output

dictionary

description

97null

ayesa98

abno1

ab:5

ab不存在dictionary中,擴充99b

cno2bc:6

257cbno

3cb:7

256b

cyes

bc在dictionary中,p = pc

99bcano

6bca:8

260a

byes

100abcno

5abc:9

public

static string decode(listarr)

string p = "";

string c = "";

for (int code : arr) else

if (code == idlecode) else

if (!p.equals(""))

p = c;

}return result.tostring();

}

手打 LZW編碼的C C 實現

lzw編碼通過建立乙個字串表,用較短的 來表示較長的字串來實現壓縮。lzw壓縮演算法是unisys的專利,有效期到2003年,所以相關演算法大多也已過期。本 只完畢了lzw的編碼與解碼演算法功能,相對網上找到的非常多 而言較為簡 cai 單 bi 了解struct 會遞迴就可以,算是長處吧。incl...

LZW編譯碼演算法實現與分析

題目 lzw編譯碼原理和實現演算法 part1.lzw編碼原理和實現演算法 lzw的編碼思想是不斷地從字元流中提取新的字串,通俗地理解為新 詞條 然後用 代號 也就是碼字表示這個 詞條 這樣一來,對字元流的編碼就變成了用碼字去替換字元流,生成碼字流,從而達到壓縮資料的目的。lzw編碼是圍繞稱為詞典的...

用python實現的LZW演算法

以前學習了一下gif的lzw演算法,不過只是學習了一下 見我以前的那篇博文 lzw for gif演算法原理和實現 沒有實踐,也沒有看看效果到底怎麼樣,因為現在zip庫很多,基本上不需要自己寫壓縮演算法了,lzw的壓縮效果也比不上它們。不過最近有個嵌入式系統上的資料記錄需求,希望把執行過程中採集的資...