前言
本篇将介紹哈夫曼壓縮算法(Huffman compression)
哈夫曼壓縮算法(Huffman compression)
衆所周知,計算機存儲資料時,實際上存儲的是一堆0和1(二進制)。
如果我們存儲一段字元:ABRACADABRA!
那麼計算機會把它們逐一翻譯成二進制,如A:01000001;B: 01000010; !: 00001010.
每個字元占8個bits, 這一整段字元則至少占12*8=96 bits。
但如果我們用一些特殊的值來代表這些字元,如:
圖中,0代表A; 1111代表B;等等。此時,存儲這段字元隻需30bits,比96bits小多了,達到了壓縮的目的。
我們需要這麼一個表格來把原資料翻譯成特别的、占空間較少的資料。同時,我們也可以用這個表格,把特别的資料還原成原資料。
首先,為了避免翻譯歧義,這個表格需滿足一個條件:任何一個字元用的值都不能是其它字元的字首。
我們舉個反例:A: 0; B: 01;這裡,A的值是B的值的字首。如果壓縮後的資料為01xxxxxx,x為0或者1,那麼這個資料應該翻譯成A1xxxxxx, 還是Bxxxxxxx?這樣就會造成歧義。
然後,不同的表格會有不同的壓縮效果,如:
這個表格的壓縮效果更好。
那麼我們如何找到最好的表格呢?這個我們稍後再講。
為了友善閱讀,這個表格是可以寫成一棵樹的:
這棵樹的節點左邊是0,右邊是1。任何含有字元的節點都沒有非空子節點。(即上文提及的字首問題。)
這棵樹是在壓縮的過程中建成的,這個表格是在樹形成後建成的。用這個表格,我們可以很簡單地把一段字元變成壓縮後的資料,如:
原資料:ABRACADABRA!
表格如上圖。
令壓縮後的資料為S;
第一個字元是A,根據表格,A:11,故S=11;
第二個字元是B,根據表格,B:00,故S=1100;
第三個字元是R,根據表格,R:011,故S=1100011;
如此類推,讀完所有字元為止。
壓縮搞定了,那解壓呢?很簡單,跟着這棵樹讀就行了:
壓縮後的資料S=11000111101011100110001111101
記住,讀到1時,往右走,讀到0時,往左走。
令解壓後的字元串為D;
從根節點出發,第一個數是1,往右走:
第二個數是1,往右走:
讀到有字元的節點,傳回此字元,加到字元串D裡。D:A;
傳回根節點,繼續讀。
第三個數是0,往左走:
第四個數是0,往左走:
讀到有字元的節點,傳回此字元,加到字元串D裡。D:AB;
傳回根節點,繼續讀。
第五個數是0,往左走:
第六個數是1,往右走:
第七個數是1,往右走:
讀到有字元的節點,傳回此字元,加到字元串D裡。D:ABR;
傳回根節點,繼續讀。
如此類推,直到讀完所有壓縮後的資料S為止。
壓縮與解壓都搞定了之後
我們需要先把原資料讀一遍,并把每個字元出現的次數記錄下來。如:
ABRACADABRA!中,A出現了5次;B出現了2次;C出現了1次;D出現了1次;R出現了2次;!出現了1次。
理論上,出現頻率越高的字元,我們給它一個占用空間越小的值,這樣,我們就可以有最佳的壓縮率
由于哈夫曼壓縮算法這塊涉及内容較多 ,文章篇幅很長;全文全方面講解了Compose布局的各方面知識。更多Android前言技術進階,我自薦一套 《完整的Android的資料,以及一些視訊課講解》
有需要的同學可以在評論區下方留言 “進階” 或 “筆記” 或者直接私信我 即可免費擷取
最後我想說:
對于程式員來說,要學習的知識内容、技術有太多太多,要想不被環境淘汰就隻有不斷提升自己,從來都是我們去适應環境,而不是環境來适應我們
技術是無止境的,你需要對自己送出的每一行代碼、使用的每一個工具負責,不斷挖掘其底層原理,才能使自己的技術升華到更高的層面
Android 架構師之路還很漫長,與君共勉