1.什么是MTF
MTF(move-to-front)是一種數據編碼方式,用於提高數據壓縮技術效果。
在數據壓縮算法中,MTF可以作為一個額外的步驟。也就是說 ,可以先進行MTF編碼,在進行數據壓縮。
2.MTF基本原理
主要使用的是數據的”空間局部性“,也就是最近出現過的字符很可能在接下來的文本附近再次出現。
MTF的主要思想是:
(1)維護一個文本字符集大小的棧,“recently used symbols”(最近訪問過的字符),其中每個不同的字符在其中占一個位置,位置從0開始編號。
(2)掃描需要重新編碼的文本數據,對於每個掃描到的字符,使用該字符在“recently used symbols”中的index替換,並將該字符提到“recently used symbols”的棧頂位置(index為0的位置)。
(3)轉到(2),直到文本掃描結束。
使用MTF,對於許多連續的、相同的字符,將被替換為多個0;最近使用過的字符,會被小的index替換;最近很久沒有使用過的字符,會被較大的index替換。MTF完成之后,文本就可以使用一串數字表示,如果文本數據具有較好的空間局部性,這些數字會很小,便於壓縮。
3.MTF圖解
(1)先建立字符集大小的棧,“recently used symbols”,這里只考慮26個小寫字母a~z。
recently used symbols:queue=(abcdefghijklmnopqrstuvwxyz)。
其中字符在棧中的位置表示該字符的index。起初,字符a的index為0,b的index為1,以此類推,z的index為25。
(2)掃描文本,如”bananaaa“。
編碼如下:
如上,bananaaa經MTF之后變成了list=(1,1,13,1,1,1,0,0)。MTF只可逆的過程,只要記錄下轉換之前的queue和轉換之后的list,就完全可以快速的回復原始文本數據。
解碼如下:
4.MTF數據轉換的使用
MTF轉換主要是利用空間局部性原理來減少信息熵。因為最近訪問的字符總是出現在“recently used symbols”的前面位置,如果字符的空間局部性較好,編碼之后就會出現很多小的數字,如”0“或”1“。然而,並不是所有的文本數據,都具有較好的局部相關性。
一個重要的應用就是基於Burrows–Wheeler transform壓縮算法。Burrows-Wheeler transform能將文本轉換為局部相關性很好的序列。
一般壓縮可以將文本先使用Burrows–Wheeler transform生成局部相關性很好的序列,再使用MTF減少信息熵,最后再進行壓縮。
5.MTF轉換代碼實例
下面的代碼是對文本進行move-to-front數據編碼:
1 #include <iostream> 2 #include <algorithm> 3 #include <string> 4 #include <list> 5 using namespace std; 6 7 int MTF_transform(const string &text,int* result_MTF,list<char> &mylist){ 8 list<char>::iterator it; 9 for(int i=0;i<text.size();i++){ 10 it=find(mylist.begin(), mylist.end(),text[i]); ///查找當前字符 11 result_MTF[i]=distance(mylist.begin(),it); ///保存當前字符在mylist中的索引 12 mylist.erase(it); ///刪除元素 13 mylist.push_front(text[i]); ///把當然元素添加到index為0的位置 14 } 15 return 0; 16 } 17 18 int main(int argc,char* argv[]) 19 { 20 string text = "bananaaa"; 21 int *result_MTF = new int[text.size()]; 22 list<char> mylist; 23 for(int i=0;i<26;i++){ 24 mylist.push_back('a'+i); 25 } 26 27 MTF_transform(text,result_MTF,mylist); 28 for(int i=0;i<text.size();i++){ 29 cout<<result_MTF[i]<<" "; 30 } 31 delete [] result_MTF; 32 return 0; 33 }