關於LZW算法的壓縮與解壓縮
LZW算法是基於字典查找的一種優秀算法,該算法的名稱來源於它的三個創始人Lemple-Ziv-Welch。它的壓縮比通常在1:1--1:3之間,一些數據重復較多的文件采用此壓縮方法的效果會更好。下面將詳細闡述LZW算法的壓縮與解壓縮過程。
1:LZW算法的壓縮過程
1.1 准備工作:
在講述壓縮過程之前有必要先弄清楚與它相關的幾個名詞:
“charstream”:字符流,表示從原始文件中輸出的數據流。
“prefix_character”:前綴字符,代表當前字符最直接的前一個字符。
“current_character”:當前字符,顧名思意就是當前接收到的一個字符,它與prefix_character可以組成一個字符串。
“string”:字符串,由前綴字符和當前字符組成。
“code_table”:代碼表,存儲一個新的字符串的代碼編號。
“element”:元素,字符流中的不同的單個數據元素,它的代碼是在編碼前給它按順序編制
1.2具體實現:
在了解了上面的一些概念以后,下面正式進入壓縮算法步驟:
① 從字符流中獲取第一個字符把它的值賦給prefix_character
② 字符流是否結束,沒結束就從字符流中再取一個字符賦給current_character,字符結束首先輸出prefix_character,然后退出程序。
③ String = prefix_character+current_character是否在code_table當中?
④ 在code_table當中,就把string的代碼編號賦給prefix_character,轉往②步進行。
⑤ 沒在cde_table當中,就把string存儲到code_table當中去,輸出prefix_charracter,並且把current_character賦給prefix_character,再轉往②執行。
1,.3舉例分析:
被編碼的字符串
位置 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
字符 |
A |
B |
B |
A |
B |
A |
B |
A |
C |
此例中:A,B,C是element,9個字符組成了char_stream
步驟 |
位置 |
詞典(code_table) |
輸出 |
|
1 |
|
(1) |
A |
|
2 |
|
(2) |
B |
|
3 |
|
(3) |
C |
|
4 |
|
(4) |
AB |
(1) |
5 |
|
(5) |
BB |
(2) |
6 |
|
(6) |
BA |
(2) |
7 |
|
(7) |
ABA |
(4) |
8 |
|
(8) |
(7)C |
(7) |
在第4步中,A為前綴,B為當前字符,在第7步當中先得到一個string是AB,但是AB已經在code_table當中了,所以這時以AB作為前綴,后取一個字符A,這時(4)+A在code_table當中沒有,所以把這個string放到code_table中去,編號為(7),這時就把(7)作為前綴,繼續下面的編碼。
2:LZW的解壓縮過程
2.1在講述解壓縮的具體實現過程之前,首先把上面壓縮字符表對應的解壓縮表給出,再對照解壓縮表給出解壓縮的具體過程。
步驟 |
代碼 |
詞典 |
輸出 |
|
|
|
(1) |
A |
|
|
|
(2) |
B |
|
|
|
(3) |
C |
|
1 |
(1) |
-- |
-- |
A |
2 |
(2) |
(4) |
AB |
B |
3 |
(2) |
(5) |
BB |
B |
4 |
(4) |
(6) |
BA |
AB |
5 |
(7) |
(7) |
ABA |
ABA |
6 |
(3) |
(8) |
(7)C |
C |
2.2 LZW解壓縮具體步驟:
從上面的解壓縮表可以看出以下幾條:
當遇到小於3的代碼時就直接輸出,如A,B,C;
當遇到大於3的代碼,並且在code_table當中存在的代碼值時就到code_table當中去遍歷它存儲的字符,並且把它輸出。如第4步中的(4);
當遇到大於3,但是在code_table當中沒有存儲的就把前綴的第1個字符作為當前字符,把這個當前字符和前綴同時輸出,並且把他們存儲在code_table當中。如(7),它把AB的第1個字符加在AB之后將其作為一個string輸出,並且存儲在code_table當中。
具體解壓步驟如下:
① 讀取第一個字符,輸出它,並且把它賦給prefix_character
② 讀取下一個字符,是否文件已經結束,沒有結束,就把該字符賦給current_character,該字符是否大於N(基本字符element的個數)?
③ 大於N,是否在code_table當中?
④ 沒在code_table當中,將prefix_character+prefix_character的第1個字符輸出,並且賦給string 存儲當code_table當中去,同時把該string賦給prefix_character,轉向②執行。
⑤ 在code_table當中,遍歷current_character的所有字符,並且輸出它,把current_character賦給prefix_character,轉向②執行。
⑥ 小於N,輸出current_character,並且把cureent_character賦給prefix_character,轉向②執行。