六:親自嘗試壓縮數據

0 開篇

(1)文件儲存的基本單位是什麼?
     字節(1字節=8位)
(2)DOC、LZH和TXT這些擴展名中,哪個是壓縮文件的擴展名?
     LZH   (LZH是用LHA等工具壓縮過的文件的擴展名)
(3)文件內容用「數據的值*循環次數」來表示的壓縮方法時RLE算法仍是哈夫曼算法?
     RLE算法
(4)在Windows計算機常用的SHIFT JIS字符編碼中,1個半角英數是用幾個字節的數據來表示的?
     1字節=8位
(5)BMP(BITMAP)格式的圖像文件,是壓縮過的嗎?
     沒有壓縮
(6)可逆壓縮和非可逆壓縮的不一樣點是什麼?
     壓縮後的數據能復原的是可逆壓縮,沒法復原的是非可逆壓縮。

1 文件以字節位單位保存

     文件是將數據存儲在磁盤等存儲媒介中的一種形式。程序文件中存儲數據的單位是字節。文件的大小之因此用xxKB、xxMB等來表示,就是由於文件是以字節(B=Byte)爲單位來存儲的。
     文件就是字節數據的集合。用1字節(=8位)表示的字節數據有256種,用二進制數來表示的話,其範圍就是00000000~11111111.若是文件中存儲的數據時文字,那麼該文件就是文本文件。若是是圖形,那麼該文件就是圖像文件。在任何狀況下,文件中的字節數據都是連續存儲的。

2 RLE算法的機制

  以示例來描述一下這個壓縮機制:AAAAAABBCDDEEEEEF算法

  因爲半角字母中,1個字符是做爲1個字節的數據被保存在文件中的。所以上述的文件大小就是17字節。好,那咱們如今開始以「編程

字符*重複次數」這樣的表現方式來壓縮。上述文件內容就變爲A6B2C1D2E5F1來表示,這樣只剩12字節,所以結果就將原文件壓縮了12字節/17字節=70% 。

  上述的壓縮方法稱爲RLE(Run Length Encoding,行程長度編碼)算法。RLE算法是一種很好的壓縮算法,常常被用於壓縮傳真的圖像等。由於圖像文件本質上也是字節數據的集合體。工具

3 RLE算法的缺點

  然而,在實際的文本中,一樣字符屢次重複出現的狀況並很少見。雖然針對相同數據常常連續出現的圖像、文件等,RLE算法能夠發揮不錯的效果,但它並不適合文本文件的壓縮。不過,由於該壓縮機制很是簡單,所以使用RLE算法的程序也相對更容易編寫。編碼

     好,如今就來看一個反例:This is a pen.
     這個文本採用RLE算法對其進行壓縮後,就變成了T1h1i1s1 1i1s1 1a1p1e1n1.1,這樣28個字符,是壓縮前的2倍。因爲文章中字符大量連續出現的狀況並很少見,所以,使用RLE算法後,大部分字符後面都會加上1,這樣一來,壓縮後的文件天然變成了以前的2倍。
 

4 經過莫爾斯編碼來看哈夫曼算法的基礎

   哈夫曼算法是哈夫曼於1952年提出來的壓縮算法。
      爲了更好地理解哈夫曼算法,首先你們要拋棄掉「半角英文數字的1個字節是1個字節(8位)的數據」這個概念。文本文件是由不一樣類型的字符組合而成的,並且不一樣的字符出現的次數也是不一樣的。例如,在某一個文本文件中,A出現了100次左右,Q僅用到了3次,相似這樣的狀況是很常見的。而哈夫曼算法的關鍵就在於「屢次出現的數據用小於8位的字節數來表示,不經常使用的數據則能夠用超過8位的字節數來表示」。A和Q都用8位來表示時,原文件的大小就是100*8+3*8=824位,而假設A用2位,Q用10位來表示,壓縮後的大小就是100*2+3*10=230位。
      不過有一點須要注意,不論是不滿8位的數據,仍是超過8位的數據,最終都要以8位爲單位保存到文件中。這時由於磁盤是以字節(8位)爲單位來保存數據的。
      爲了更好地理解哈夫曼算法,先來看一下莫爾斯編碼。莫爾斯編碼不是經過語言,而是經過「嗒 嘀 嗒 嘀」這些長點和短點的組合來傳遞文本信息的。

  莫爾斯編碼把通常文本中出現頻率高的字符用短編碼來表示。這裏所說的出現頻率,不是經過對出版物等文章進行統計調查得來的,而是根據印刷行業的印刷活字數目而肯定的。如上表所示,假設表示短點的位是1,表示長點的位時11的話,那麼E(嘀)這一字符的數據就能夠用1位的1來表示,C(嗒嘀嗒嘀)這一字符的數據就能夠用9位的110101101來表示。在實際的莫爾斯編碼中。若是短點的長度是1,長點的長度就是3,短點和長點的間隔就是1.這裏的長度指的是聲音的長度。接下來,就讓咱們嘗試一下用莫爾斯編碼來表示前面提到的AAAAAABBCDDEEEEEF這個17個字符的文本。在莫爾斯編碼中,各個字符之間須要加入表示間隔的符號。這裏咱們用00來進行區分。所以,就編程了A*6+B*2+C*1+D*2+E*5+F*1+字符間隔*16=4*6+8*2+9*1+6*2+1*5+8*1+2*16=106位=14字節。由於文件只能以字節位單位來存儲數據,所以不滿1字節的部分就要圓整成1個字節。若是全部字符佔用的空間都是1個字節(8位),這樣文本中列出來的17個字符=17字節,那麼摩爾斯電碼的壓縮比率就是14/17=82%。3d

5 用二叉樹實現哈夫曼編碼

  哈夫曼算法是指,爲各壓縮對象文件分別構造最佳的編碼體系,並以該編碼體系爲基礎來進行壓縮。所以,用什麼樣式的編碼(哈夫曼編碼)對數據進行分割,就要由各個文件而定。用哈夫曼算法壓縮過的文件中,存儲着哈夫曼編碼信息和壓縮過的數據,以下圖:對象

  接下來,咱們嘗試一下把AAAAAABBCDDEEEEEF這些字符按照「出現頻率高的字符用盡可能少的位數編碼來表示」這一原則進行整理。咱們假定用下面的方案:blog

  在上述的方案中,隨着出現頻率的下降,字符編碼信息的數據位數也在逐漸增長,從開始的1位、2位依次增長到3位。不過這個編碼體系是存在問題的,假設100這個3位的編碼,它的意思是用一、0、0這3個編碼來表示E、A、A呢?仍是用十、0這兩個編碼來表示B、A呢?亦或是用100來表示C呢?這些都沒法進行區分。所以,若是不加入用來區分字符的符號,這個編碼就沒法使用。
       而在哈夫曼算法中,經過藉助哈夫曼樹構造編碼體系,即便在不使用字符區分符號的狀況下,也能夠構建可以明確進行區分的編碼體系。接下來咱們就看一下如何製做哈夫曼樹。

6 哈夫曼算法可以大幅提高壓縮比率

     使用哈夫曼樹後,出現頻率越高的數據所佔用的數據位數就越少,並且數據的區分也能夠很清晰地實現。
     經過上一小節的介紹能夠發現,在用枝條鏈接數據時,咱們是從出現頻率較低的數據開始的,這就意味着出現頻率越低的數據到達根部的枝條數就越多,而枝條數越多,編碼的位數也就隨之增多了。從用哈夫曼算法壓縮過的文件中讀取數據後,就會以位爲單位對該數據進行排查,並與哈夫曼樹進行比較看是否到達了目標編碼,這就是爲何哈夫曼算法能夠對數據進行區分的緣由。例如,10001這個使用上圖所示的哈夫曼編碼做成的5位數據,到達100時,對照哈夫曼樹的數據,該數據表示的是B這個字符。好,介紹了這麼多,讓咱們能夠來看看哈夫曼算法的壓縮比率:
用哈夫曼編碼表示AAAAAABBCDDEEEEEF:0000000000001001001101011010101010101111,40位,壓縮前位17字節,目前只須要5個字節,固然,這裏不包括哈夫曼編碼信息的狀況。但這個也實現了很高的壓縮比率了。
 

7 可逆壓縮和非可逆壓縮

     Windows的標準圖像數據形式爲BMP,是徹底未壓縮的。除此以外,還有其餘各類格式的圖像數據形式。好比JPEG、TIFF、GIF格式等。與BMP格式不一樣的是,這些圖像數據都會用一些技法來對數據進行壓縮。
     在大多數狀況下,並不要求壓縮後的圖像文件必須還原到與壓縮前同等的質量。與之相比,程序的EXE文件以及每一個字符、數值都具備具體含義的文本文件則必需要還原到和壓縮前一樣的內容。而對於圖像文件來講,即便有時沒法還原到壓縮前那樣鮮明的圖像狀態,但只要肉眼看不出什麼區別,有一些模糊也勉強能夠接受。這裏,咱們把能還原到壓縮前狀態的壓縮稱爲可逆壓縮,沒法還原到壓縮前狀態的壓縮稱爲非可逆壓縮。

 

   JPEG格式和GIF格式的圖像文件有一些模糊,是由於他們是非可逆壓縮,所以還原後會有一些模糊。而GIF格式的文件雖然是可逆壓縮,但由於有色數不能超過256色的限制,因此還原後顏色信息會有一些缺失,進而致使了圖像模糊。TIFF格式的圖像文件雖然不模糊,但卻比原始的BMP格式文件還要大,由於TIFF格式的文件中帶有各類標籤信息。字符編碼

相關文章
相關標籤/搜索