本發(fā)明涉及數(shù)據(jù)庫(kù)領(lǐng)域,特別涉及一種利用前綴樹(shù)進(jìn)行數(shù)據(jù)壓縮的方法、裝置、系統(tǒng)和計(jì)算機(jī)程序產(chǎn)品。
背景技術(shù):
數(shù)據(jù)檢索(dataretrieval)是指通過(guò)數(shù)據(jù)庫(kù)管理系統(tǒng)(dbms)從數(shù)據(jù)庫(kù)中獲得數(shù)據(jù)的處理。不同類(lèi)型的數(shù)據(jù)存儲(chǔ)形式適用于不同類(lèi)型的應(yīng)用,并且一些類(lèi)型的存儲(chǔ)形式則特別適用于執(zhí)行特定的處理任務(wù)。
例如,樹(shù)形結(jié)構(gòu)是一種普遍采用的非線性數(shù)據(jù)存儲(chǔ)形式,其通過(guò)一組相連的結(jié)點(diǎn)的形式表示,以便于描述具有分支和層次特性的數(shù)據(jù)集合。
在樹(shù)形結(jié)構(gòu)中,經(jīng)常會(huì)用到以下基本術(shù)語(yǔ):
根結(jié)點(diǎn):樹(shù)中位于頂端的結(jié)點(diǎn);
子結(jié)點(diǎn):沿著離開(kāi)根結(jié)點(diǎn)的方向,直接與前一結(jié)點(diǎn)相連的結(jié)點(diǎn);
父結(jié)點(diǎn):與子結(jié)點(diǎn)對(duì)應(yīng)的結(jié)點(diǎn);
后代結(jié)點(diǎn):通過(guò)重復(fù)地由一父結(jié)點(diǎn)前往一子結(jié)點(diǎn)可達(dá)的結(jié)點(diǎn);
祖先結(jié)點(diǎn):通過(guò)重復(fù)地由一子結(jié)點(diǎn)前往其父結(jié)點(diǎn)可達(dá)的結(jié)點(diǎn);
葉結(jié)點(diǎn)/外部結(jié)點(diǎn):沒(méi)有子結(jié)點(diǎn)的結(jié)點(diǎn);
內(nèi)部結(jié)點(diǎn):具有至少一個(gè)子結(jié)點(diǎn)的結(jié)點(diǎn);
邊:從父結(jié)點(diǎn)到子結(jié)點(diǎn)的連接;
子樹(shù):由樹(shù)中的一個(gè)結(jié)點(diǎn)及其全部后代結(jié)點(diǎn)組成的樹(shù)。
以下介紹數(shù)據(jù)壓縮領(lǐng)域的近期發(fā)展。
前綴樹(shù)
前綴樹(shù)(又稱(chēng)trie樹(shù)、字典樹(shù))是一種類(lèi)型的樹(shù)形結(jié)構(gòu)。在前綴樹(shù)中,一個(gè)結(jié)點(diǎn)的全部后代結(jié)點(diǎn)具有相同的前綴,該前綴即為關(guān)聯(lián)于該結(jié)點(diǎn)的字符串(根結(jié)點(diǎn)對(duì)應(yīng)于空的字符串)。并且,在前綴樹(shù)中,結(jié)點(diǎn)并不存儲(chǔ)與其關(guān)聯(lián)的鍵,而是通過(guò)其在樹(shù)中所處的位置來(lái)定義與其關(guān)聯(lián)的鍵,每個(gè)結(jié)點(diǎn)都對(duì)應(yīng)從其父結(jié)點(diǎn)鏈接過(guò)來(lái)的邊。
一個(gè)標(biāo)準(zhǔn)的前綴樹(shù)具有以下基本性質(zhì):1)根結(jié)點(diǎn)無(wú)對(duì)應(yīng)的邊(每條邊包含一個(gè)字符),除根結(jié)點(diǎn)外每一個(gè)結(jié)點(diǎn)都對(duì)應(yīng)一條邊(從而包含一個(gè)字符);2)一個(gè)結(jié)點(diǎn)包含的字符在其對(duì)應(yīng)的邊上標(biāo)注,從根結(jié)點(diǎn)到某一結(jié)點(diǎn)的路徑(即,對(duì)應(yīng)的一組邊)上經(jīng)過(guò)的字符連接起來(lái),為該結(jié)點(diǎn)對(duì)應(yīng)的字符串(即,鍵);3)每個(gè)結(jié)點(diǎn)的所有子結(jié)點(diǎn)包含的字符都不相同。
圖1示出了前綴樹(shù)的一個(gè)實(shí)例,該前綴樹(shù)由abc、abcd、abd、b、bcd、efg、hii這7個(gè)字符串構(gòu)成。圖中雙圈結(jié)點(diǎn)表示該節(jié)點(diǎn)具有終止?fàn)顟B(tài)(即前綴樹(shù)中存在與該節(jié)點(diǎn)對(duì)應(yīng)的字符串),單圈結(jié)點(diǎn)表示該節(jié)點(diǎn)不具有終止?fàn)顟B(tài)。
前綴樹(shù)支持以下基本操作。
正向搜索:指在前綴樹(shù)中搜索一個(gè)已知的字符串。從根結(jié)點(diǎn)開(kāi)始,搜索字符串的第一個(gè)字符,并根據(jù)該字符對(duì)應(yīng)的邊轉(zhuǎn)到相應(yīng)的子樹(shù)繼續(xù)進(jìn)行搜索;在相應(yīng)的子樹(shù)上,搜索字符串的第二個(gè)字符,并進(jìn)一步選擇相應(yīng)的子樹(shù)進(jìn)行搜索;進(jìn)行迭代操作,直到在某個(gè)結(jié)點(diǎn)處,如果所有字符都被找到,則讀取附在該結(jié)點(diǎn)上的信息,完成搜索,否則表示未搜索到字符串。
反向搜索:指在前綴樹(shù)中恢復(fù)一個(gè)位置已知的字符串。從前綴樹(shù)中的任意結(jié)點(diǎn)開(kāi)始,根據(jù)已知的路徑指示沿著從子結(jié)點(diǎn)到父結(jié)點(diǎn)的方向至根結(jié)點(diǎn),從而恢復(fù)出一個(gè)字符串,然后對(duì)該字符串進(jìn)行反轉(zhuǎn),就可以得到與從根結(jié)點(diǎn)到該子結(jié)點(diǎn)的路徑匹配的字符串。
插入:首先,根據(jù)要插入的字符串通過(guò)正向搜索找到需要插入的結(jié)點(diǎn)位置。如果與要插入的字符串對(duì)應(yīng)的路徑在前綴樹(shù)中不存在,則在找到的結(jié)點(diǎn)位置處創(chuàng)建與該字符串的其余字符對(duì)應(yīng)的新結(jié)點(diǎn);如果路徑在前綴樹(shù)中存在,則將對(duì)應(yīng)的結(jié)點(diǎn)設(shè)置為具有終止?fàn)顟B(tài)(即表示存在對(duì)應(yīng)的字符串)。
刪除:首先,根據(jù)要?jiǎng)h除的字符串找到需要?jiǎng)h除的結(jié)點(diǎn)位置。如果找到的結(jié)點(diǎn)是葉結(jié)點(diǎn),則迭代地刪除對(duì)應(yīng)的各葉結(jié)點(diǎn);如果找到的結(jié)點(diǎn)是內(nèi)部結(jié)點(diǎn),則將該結(jié)點(diǎn)設(shè)置為不具有終止?fàn)顟B(tài)(即表示不存在對(duì)應(yīng)的字符串)。
需要說(shuō)明的是,在傳統(tǒng)使用指針?lè)绞奖磉_(dá)的前綴樹(shù)中,一般僅保存從父節(jié)點(diǎn)指向子結(jié)點(diǎn)的指針,因此僅支持正向搜索操作。如果在這種實(shí)現(xiàn)方式中還需要支持反向搜索操作,則還需要額外增加從子結(jié)點(diǎn)指向父結(jié)點(diǎn)的指針,占用更多的存儲(chǔ)空間。
前綴樹(shù)可以用于代替哈希表等其他類(lèi)型的數(shù)據(jù)存儲(chǔ)方式,并且可以高效地實(shí)現(xiàn)對(duì)字典類(lèi)數(shù)據(jù)的存儲(chǔ)和利用。前綴樹(shù)利用字符串的公共前綴來(lái)節(jié)約存儲(chǔ)空間,最大限度地減少無(wú)謂的字符串比較。然而,如果存在大量字符串且這些字符串基本沒(méi)有公共前綴,則相應(yīng)的前綴樹(shù)將非常消耗存儲(chǔ)空間。
壓縮前綴樹(shù)
為了提高前綴樹(shù)的空間利用率,可以對(duì)前綴樹(shù)進(jìn)行壓縮。一種可行的壓縮方式是對(duì)前綴樹(shù)中的邊進(jìn)行壓縮,即對(duì)前綴樹(shù)中的滿足預(yù)定要求的結(jié)點(diǎn)進(jìn)行合并。這種形式的前綴樹(shù)可以稱(chēng)為patricia(practicalalgorithmtoretrieveinformationcodedinalphanumeric)型前綴樹(shù)。
patricia型前綴樹(shù)對(duì)結(jié)點(diǎn)空間進(jìn)行了優(yōu)化。具體而言,在這種類(lèi)型的前綴樹(shù)中,如果一個(gè)結(jié)點(diǎn)是另一個(gè)結(jié)點(diǎn)唯一的子結(jié)點(diǎn),則可以將這兩個(gè)結(jié)點(diǎn)合并為一個(gè)結(jié)點(diǎn)。因此,在經(jīng)結(jié)點(diǎn)合并后,patricia型前綴樹(shù)中的一些邊是使用多個(gè)字符構(gòu)成的字符串來(lái)標(biāo)注的。
圖2示出了patricia型前綴樹(shù)的一個(gè)實(shí)例,該前綴樹(shù)由romane、romanus、romulus、rubens、ruber、rubicon、rubicundus等7個(gè)字符串構(gòu)成??梢钥吹皆谠撉熬Y樹(shù)中,根據(jù)上述合并條件對(duì)邊進(jìn)行了壓縮,例如,在經(jīng)過(guò)合并后,葉結(jié)點(diǎn)5與其父結(jié)點(diǎn)1之間的壓縮邊用字符串“ulus”來(lái)標(biāo)注。需要說(shuō)明的是,在一些實(shí)現(xiàn)方式中,可以對(duì)合并條件進(jìn)行額外的限定,例如,只有當(dāng)合并后的結(jié)點(diǎn)對(duì)應(yīng)的邊上的字符數(shù)目達(dá)到預(yù)定值時(shí)才進(jìn)行合并。
patricia型前綴樹(shù)適用于字符串集合中的字符串具有較長(zhǎng)的相同前綴的情況。例如,patricia型前綴樹(shù)特別適用于在ip路由領(lǐng)域中對(duì)ip地址進(jìn)行管理。
succinct型數(shù)據(jù)壓縮
succinct是近年來(lái)提出的一種無(wú)損數(shù)據(jù)壓縮方法。通過(guò)數(shù)據(jù)壓縮,使用接近信息論下邊界的存儲(chǔ)空間量,同時(shí)仍然可以實(shí)現(xiàn)高效的查詢操作。區(qū)別于傳統(tǒng)的無(wú)損數(shù)據(jù)壓縮算法,succinct型數(shù)據(jù)壓縮在不實(shí)現(xiàn)解壓的前提下仍然具有可以隨時(shí)使用這些數(shù)據(jù)的能力。
可以從空間復(fù)雜度的角度來(lái)定義succinct型數(shù)據(jù)壓縮:假設(shè)根據(jù)信息論,為了存儲(chǔ)某一數(shù)據(jù)所需要的最少比特?cái)?shù)為z,那么succinct型數(shù)據(jù)壓縮占用的存儲(chǔ)空間為z+o(z)個(gè)比特,其中,o(z)表示空間復(fù)雜度。繼續(xù)這個(gè)例子,則使用
succinct型的可索引(indexable)字典(也被稱(chēng)為rank/select字典)是多種succinct型表達(dá)方式的基礎(chǔ)。在這種字典中,存儲(chǔ)了空間u=[0...n)={0,1,...,n-1}的子集s,s一般被表示為比特?cái)?shù)組b[0...n),其中,當(dāng)且僅當(dāng)i∈s時(shí),b[i]=1。
上述succinct型可索引化字典支持rank和select兩種操作:
rank操作的表達(dá)式為rankq(x)=|{k∈[0...x]:b[k]=q}|;
select操作的表達(dá)式為selectq(x)=min{k∈[0...n):rankq(k)=x};
其中,q∈{0,1}。
rankq(x)操作的返回值為0至x元素中值為q的元素的個(gè)數(shù);
selectq(x)操作的返回值為第x個(gè)值為q的元素的位置。
如上文所述,succinct型的可索引化字典是多種succinct型表達(dá)方式的基礎(chǔ),這些表達(dá)方式包括二叉樹(shù)、k叉樹(shù)、多重集合、后綴樹(shù)/后綴數(shù)組等。以一個(gè)具有n個(gè)結(jié)點(diǎn)的二叉樹(shù)為例,可以采用2n+o(n)個(gè)比特來(lái)表示succinct型的二叉樹(shù)。
louds型前綴樹(shù)
louds(level-orderunarydegreesequence)型前綴樹(shù)是一種使用succinct方式表達(dá)的前綴樹(shù)。在louds型前綴樹(shù)中,不使用指針來(lái)表示結(jié)點(diǎn)的位置,而是使用比特?cái)?shù)組串來(lái)對(duì)結(jié)點(diǎn)進(jìn)行編碼,從而實(shí)現(xiàn)樹(shù)形結(jié)構(gòu)的高效率表達(dá)。
可以通過(guò)以下方式來(lái)構(gòu)建louds比特?cái)?shù)組串。從根結(jié)點(diǎn)出發(fā),以寬度優(yōu)先的方式遍歷一個(gè)前綴樹(shù)(即,先遍歷位于同一層各個(gè)結(jié)點(diǎn),然后再前進(jìn)到下一層的結(jié)點(diǎn))。當(dāng)發(fā)現(xiàn)一個(gè)結(jié)點(diǎn)具有d個(gè)子結(jié)點(diǎn)時(shí),使用d個(gè)1和和一個(gè)0來(lái)表示該結(jié)點(diǎn)。相應(yīng)地,葉結(jié)點(diǎn)可以一個(gè)0來(lái)表示。此外,還將一個(gè)前綴10添加到louds比特?cái)?shù)組串中,該前綴用于表示指向根結(jié)點(diǎn)的虛擬超結(jié)點(diǎn)。由此可見(jiàn),louds型前綴樹(shù)使用2n+1個(gè)比特來(lái)表述樹(shù)形結(jié)構(gòu)。圖3示出了根據(jù)上述規(guī)則構(gòu)建的louds型前綴樹(shù)的一個(gè)實(shí)例。
此外,louds型前綴樹(shù)還使用n個(gè)比特的數(shù)組(即succinct型數(shù)據(jù)壓縮中的數(shù)組b)來(lái)存儲(chǔ)各個(gè)結(jié)點(diǎn)是否具有終止?fàn)顟B(tài)(即對(duì)應(yīng)的字符串是否存在)。由此可見(jiàn),可以使用louds表達(dá)方式來(lái)實(shí)現(xiàn)包括patricia型前綴樹(shù)在內(nèi)的任一前綴樹(shù)的樹(shù)形結(jié)構(gòu),并且louds表達(dá)方式實(shí)現(xiàn)的前綴樹(shù)滿足succinct型數(shù)據(jù)壓縮的存儲(chǔ)空間要求,即z+o(z)。進(jìn)一步地,對(duì)于一個(gè)不包含壓縮邊的前綴樹(shù)而言,還可以采用n個(gè)字節(jié)(使用其中的n-1個(gè)字節(jié))的數(shù)組來(lái)存儲(chǔ)各個(gè)邊上的轉(zhuǎn)移字符。
louds型前綴樹(shù)通過(guò)succinct型數(shù)據(jù)壓縮中的rank和select操作支持查找任意結(jié)點(diǎn)的父結(jié)點(diǎn)(getparent)和子結(jié)點(diǎn)(getnthchild)。相應(yīng)地,通過(guò)查找子結(jié)點(diǎn)的操作可以實(shí)現(xiàn)正向搜索功能,并且通過(guò)查找父結(jié)點(diǎn)的操作可以實(shí)現(xiàn)反向搜索的功能。
通過(guò)以上描述,本領(lǐng)域技術(shù)人員能夠理解,可以采用結(jié)點(diǎn)合并的方式對(duì)前綴樹(shù)進(jìn)行壓縮,并且可以采用louds表示方法來(lái)表達(dá)前綴樹(shù)的樹(shù)形結(jié)構(gòu),以實(shí)現(xiàn)高效率的正向搜索和反向搜索功能。
然而,在經(jīng)過(guò)結(jié)點(diǎn)合并的前綴樹(shù)中依然有可能存在冗余。繼續(xù)圖2中的例子,可以發(fā)現(xiàn),0號(hào)結(jié)點(diǎn)到6號(hào)結(jié)點(diǎn)的壓縮邊上的字符串“ub”、1號(hào)結(jié)點(diǎn)到5號(hào)結(jié)點(diǎn)的壓縮邊上的字符串“ulus”、2號(hào)結(jié)點(diǎn)到4號(hào)結(jié)點(diǎn)的壓縮邊上的字符串“us”、10號(hào)結(jié)點(diǎn)到12號(hào)結(jié)點(diǎn)的壓縮邊上的字符串“undus”之間具有相同的前綴“u”,類(lèi)似地,其中的字符串“om”與“on”之間具有相同的前綴“o”。因此,如果能夠進(jìn)一步消除壓縮前綴樹(shù)中的冗余,則可以進(jìn)一步節(jié)約壓縮前綴樹(shù)的存儲(chǔ)空間。
技術(shù)實(shí)現(xiàn)要素:
本發(fā)明所要解決的技術(shù)問(wèn)題在于:如何進(jìn)一步消除壓縮前綴樹(shù)的數(shù)據(jù)冗余,以提高壓縮前綴樹(shù)的存儲(chǔ)空間利用率。為了解決上述技術(shù)問(wèn)題,本發(fā)明提供的具體技術(shù)方案如下。
根據(jù)本發(fā)明的一種對(duì)數(shù)據(jù)進(jìn)行壓縮的方法包括以下步驟:為第一字符串集合創(chuàng)建第一前綴樹(shù),其中所述第一字符串集合包括多個(gè)原始字符串,其中前綴樹(shù)由父-子結(jié)點(diǎn)關(guān)系連接的多個(gè)結(jié)點(diǎn)構(gòu)成,前綴樹(shù)的每條邊表示包含至少一個(gè)字符的字符串,該字符串對(duì)應(yīng)于從該條邊的父結(jié)點(diǎn)到子結(jié)點(diǎn)的狀態(tài)轉(zhuǎn)移;把所述第一前綴樹(shù)中的邊所對(duì)應(yīng)的、長(zhǎng)度至少為2的字符串作為第一字符串子集;當(dāng)所述第一字符串子集中的任一字符串滿足預(yù)定條件時(shí),將該字符串分割為二個(gè)或多個(gè)字符串片段,所述字符串片段與所述第一字符串子集中未被分割的字符串一起形成分割字符串集合;使用所述第一前綴樹(shù)和所述分割字符串集合來(lái)保存所述第一字符串集合,以利用原始字符串之間的冗余而實(shí)現(xiàn)數(shù)據(jù)壓縮。本發(fā)明還提供了對(duì)數(shù)據(jù)進(jìn)行壓縮的裝置、系統(tǒng)和計(jì)算機(jī)程序產(chǎn)品。
附圖說(shuō)明
圖1示出了示例性的標(biāo)準(zhǔn)前綴樹(shù)。
圖2示出了示例性的壓縮前綴樹(shù)。
圖3示出了示例性的louds型前綴樹(shù)。
圖4示出了示例性的嵌套結(jié)構(gòu)中的一個(gè)內(nèi)層壓縮前綴樹(shù)。
圖5示出了示例性的嵌套結(jié)構(gòu)中的另一個(gè)內(nèi)層壓縮前綴樹(shù)。
圖6示出了由檢索詞和url列表組成的示例性字符串集合。
圖7示出了與所述字符串集合對(duì)應(yīng)的壓縮前綴樹(shù)。
圖8示出了與所述字符串集合對(duì)應(yīng)的一個(gè)內(nèi)層壓縮前綴樹(shù)。
圖9示出了根據(jù)本發(fā)明的數(shù)據(jù)壓縮方法的流程圖。
圖10示出了對(duì)壓縮字符串集合進(jìn)行分割后的結(jié)果。
圖11示出了與分割后的壓縮字符串集合對(duì)應(yīng)的一個(gè)第二層壓縮前綴樹(shù)。
圖12示出了對(duì)壓縮字符串集合進(jìn)行翻轉(zhuǎn)后的結(jié)果。
圖13示出了與翻轉(zhuǎn)后的壓縮字符串集合對(duì)應(yīng)的一個(gè)第三層壓縮前綴樹(shù)。
圖14示出了示例性的最內(nèi)層字符串?dāng)?shù)組。
圖15示出了使用所述最內(nèi)層字符串?dāng)?shù)組來(lái)表示多個(gè)字符串的示例。
圖16示出了根據(jù)本發(fā)明的一個(gè)數(shù)據(jù)壓縮系統(tǒng)的框圖。
具體實(shí)施方式
以下結(jié)合附圖通過(guò)實(shí)施例的形式來(lái)描述本發(fā)明的具體實(shí)施方式,以便于本領(lǐng)域技術(shù)人員理解本發(fā)明的目的、技術(shù)方案和優(yōu)點(diǎn)。本領(lǐng)域技術(shù)人員可以理解,以實(shí)施例的形式描述的具體實(shí)施方式僅僅是示例性的,而在不具備這些具體內(nèi)容的情況下也能夠?qū)崿F(xiàn)本專(zhuān)利的發(fā)明構(gòu)思。
如上文所述,在經(jīng)過(guò)結(jié)點(diǎn)合并的patricia型前綴樹(shù)中依然有可能存在冗余,針對(duì)這一問(wèn)題可以進(jìn)一步通過(guò)嵌套(nest)的方式對(duì)前綴樹(shù)進(jìn)行優(yōu)化。
在進(jìn)行嵌套操作時(shí),先根據(jù)一個(gè)初始的字符串集合strset1創(chuàng)建一個(gè)patricia型前綴樹(shù)(壓縮前綴樹(shù)1),并將該壓縮前綴樹(shù)中壓縮邊上的字符串收集起來(lái),構(gòu)成另一個(gè)字符串集合strset2。然后,基于字符串集合strset2創(chuàng)建另一個(gè)內(nèi)層的patricia型前綴樹(shù)(壓縮前綴樹(shù)2),并將壓縮前綴樹(shù)1中所收集的邊對(duì)應(yīng)的結(jié)點(diǎn)關(guān)聯(lián)到壓縮前綴樹(shù)2中的相應(yīng)結(jié)點(diǎn)。通過(guò)以上方式可以獲得具有一層嵌套關(guān)系的patricia型前綴樹(shù)。
圖4示出了基于圖2所示的patricia型前綴樹(shù)(壓縮前綴樹(shù)1)進(jìn)行嵌套操作后生成的一個(gè)內(nèi)層patricia型前綴樹(shù)(壓縮前綴樹(shù)2)。具體而言,在創(chuàng)建壓縮前綴樹(shù)2時(shí),先提取前綴樹(shù)1中具有兩個(gè)或更多個(gè)字符的邊上對(duì)應(yīng)的字符串om、ub、ulus、an、ic、us、ns、on、undus并生成字符串集合strset2。然后可以基于字符串strset2以遞歸的方式生成壓縮前綴樹(shù)2。在壓縮前綴樹(shù)1所提取字符串對(duì)應(yīng)的結(jié)點(diǎn)處可以保存指向壓縮前綴樹(shù)2中對(duì)應(yīng)結(jié)點(diǎn)(例如,葉結(jié)點(diǎn))的指針(例如,一個(gè)整數(shù)id),以用于從前綴樹(shù)2中進(jìn)行反向搜索(即,從葉結(jié)點(diǎn)往根結(jié)點(diǎn)的方向前進(jìn)),得到相應(yīng)的字符串。在一些實(shí)施例中,如果壓縮前綴樹(shù)2中依然存在較長(zhǎng)的邊,則可以通過(guò)上述方式繼續(xù)執(zhí)行嵌套操作,以生成更內(nèi)層的壓縮前綴樹(shù)。
另外,在一些類(lèi)型的數(shù)據(jù)中,字符可能具有較多的相同后綴(例如,漢語(yǔ)拼音tang、zhang、wang等等)。針對(duì)這種情況,可以先將各個(gè)字符串翻轉(zhuǎn),然后基于由翻轉(zhuǎn)后的字符串組成字符串集合來(lái)生成內(nèi)層的壓縮前綴樹(shù)。繼續(xù)上面的例子,作為一種實(shí)現(xiàn)方式,在生成壓縮前綴樹(shù)2之前可以先將所提取的各個(gè)字符串翻轉(zhuǎn)得到由mo、bu、sulu、na、ci、su、sn、no、sudnu組成的字符串集合strset2’,然后基于strset2’來(lái)生成壓縮前綴樹(shù)2’。圖5示出了所生成的壓縮前綴樹(shù)2’,可以發(fā)現(xiàn)與壓縮前綴樹(shù)2相比,壓縮前綴樹(shù)2’中具有更多的相同前綴,從而可以進(jìn)一步提高存儲(chǔ)空間的利用率。本領(lǐng)域技術(shù)人員能夠理解,上述的例子僅是示例性的,在實(shí)際情況中,由于字符串的數(shù)量更多,字符串翻轉(zhuǎn)操作的作用將更為明顯。
雖然與未經(jīng)嵌套處理的patricia型前綴樹(shù)相比,通過(guò)嵌套操作可以提高前綴樹(shù)的空間利用率,但是在一些類(lèi)型的應(yīng)用中,如果一個(gè)壓縮邊上對(duì)應(yīng)的字符串過(guò)長(zhǎng),那么僅僅通過(guò)嵌套操作可能依然無(wú)法有效提高patricia型前綴樹(shù)的存儲(chǔ)空間利用率。
舉例而言,在統(tǒng)一資源定位符(url,即網(wǎng)址)搜索的應(yīng)用中,可以采用搜索詞加url列表的方式來(lái)存儲(chǔ)數(shù)據(jù),形如“搜索詞\turl1url2url3…”,其中,\t表示一個(gè)tab字符,多個(gè)url之間則用空格分隔。圖6中的表格示出了這種類(lèi)型應(yīng)用中數(shù)據(jù)的一個(gè)實(shí)例,其中包括由三個(gè)數(shù)據(jù)條目組成的字符串集合,每個(gè)條目構(gòu)成一個(gè)長(zhǎng)字符串,包括與一個(gè)人名搜索詞對(duì)應(yīng)的拼音串以及對(duì)應(yīng)的多個(gè)url搜索結(jié)果。由于三個(gè)長(zhǎng)字符串具有共同的前綴“xusong”,因此可以在創(chuàng)建前綴樹(shù)時(shí)對(duì)應(yīng)進(jìn)行合并。
圖7示出了基于上述三個(gè)數(shù)據(jù)條目創(chuàng)建的patricia型前綴樹(shù)(壓縮前綴樹(shù)1)。如圖7所示,三個(gè)字符串具有共同的前綴“xusong”,并且其中的兩個(gè)字符串還具有共同的前綴“qin”。進(jìn)一步地,圖8示出了對(duì)壓縮前綴樹(shù)1執(zhí)行嵌套操作后得到的內(nèi)層patricia型前綴樹(shù)(壓縮前綴樹(shù)2)。可以發(fā)現(xiàn),由于在壓縮前綴樹(shù)2中三個(gè)長(zhǎng)字符串不再具有相同的前綴,此時(shí)嵌套操作并未有效提高前綴樹(shù)的空間利用率,同時(shí)由于需要額外的空間存儲(chǔ)多個(gè)前綴樹(shù)中結(jié)點(diǎn)之間的鏈接關(guān)系,因此可能會(huì)降低前綴樹(shù)的空間利用率。
針對(duì)上述問(wèn)題,可以先對(duì)字符串集合中的一些字符串進(jìn)行分割,然后基于分割后的字符串來(lái)創(chuàng)建壓縮前綴樹(shù)。
圖9示出了根據(jù)本發(fā)明的一個(gè)實(shí)施例的字符串集合壓縮方法的流程圖,其中包括步驟s901-s904。
步驟s901:為第一字符串集合創(chuàng)建第一前綴樹(shù),該第一字符串集合包括多個(gè)原始字符串。在一個(gè)實(shí)施例中,所述第一前綴樹(shù)是patricia型前綴樹(shù),該前綴樹(shù)由父-子結(jié)點(diǎn)關(guān)系連接的多個(gè)結(jié)點(diǎn)構(gòu)成,并且前綴樹(shù)的每條邊表示包含至少一個(gè)字符的字符串,該字符串對(duì)應(yīng)于從該條邊的父結(jié)點(diǎn)到子結(jié)點(diǎn)的狀態(tài)轉(zhuǎn)移。
在另一個(gè)實(shí)施例中,在創(chuàng)建前綴樹(shù)時(shí),只有合并后結(jié)點(diǎn)對(duì)應(yīng)的邊包含的字符達(dá)到預(yù)定數(shù)目時(shí),才將其作為一個(gè)字符串并將對(duì)應(yīng)的結(jié)點(diǎn)合并,否則不對(duì)結(jié)點(diǎn)進(jìn)行合并,此時(shí)對(duì)應(yīng)的邊僅包含一個(gè)字符。該預(yù)定數(shù)目可以根據(jù)具體實(shí)現(xiàn)方式靈活設(shè)定。本領(lǐng)技術(shù)人員不難理解,預(yù)定數(shù)目至少為2,并且優(yōu)選地,可以將其設(shè)定為3或更大的值。
步驟s902:把所述第一前綴樹(shù)中的邊所對(duì)應(yīng)的、長(zhǎng)度至少為2的字符串作為第一字符串子集。
在所創(chuàng)建的前綴樹(shù)中,經(jīng)合并的結(jié)點(diǎn)對(duì)應(yīng)的邊上的字符串的長(zhǎng)度至少為2,將這些字符串收集起來(lái)以生成一個(gè)字符串子集。如上文所述,可以先對(duì)這些字符串進(jìn)行翻轉(zhuǎn),然后在基于翻轉(zhuǎn)的字符串生成字符串子集。
步驟s903:當(dāng)所述第一字符串子集中的任一字符串滿足預(yù)定條件時(shí),將該字符串分割為二個(gè)或多個(gè)字符串片段,并且所述字符串片段與所述第一字符串子集中未被分割的字符串一起形成一個(gè)分割字符串集合。
在一個(gè)實(shí)施例中,如果字符串子集中的一個(gè)字符串的長(zhǎng)度達(dá)到預(yù)定值,則可以對(duì)其進(jìn)行分割操作,以得到多個(gè)對(duì)應(yīng)的字符串片段。在一個(gè)實(shí)施例中,可以把字符串中所包含的預(yù)定符號(hào)作為分割標(biāo)記符來(lái)進(jìn)行分割操作,舉例而言,預(yù)定符號(hào)可以是一個(gè)或多個(gè)空格、tab符號(hào)、分號(hào)以及其他符號(hào)。在另一個(gè)實(shí)施例中,可以將字符串與預(yù)定字符串庫(kù)進(jìn)行匹配以尋找所述字符串中的匹配片段,從而可以將字符串分割為盡量長(zhǎng)的與預(yù)定字符串庫(kù)匹配的片段。本領(lǐng)域技術(shù)人員可以理解,上述字符串分割方式僅是示例性的,可以根據(jù)需要或者根據(jù)長(zhǎng)字符串的特性采用不同的方式來(lái)進(jìn)行分割。
步驟s904:使用所述第一前綴樹(shù)和所述分割字符串集合來(lái)保存所述第一字符串集合,以利用原始字符串之間的冗余而實(shí)現(xiàn)數(shù)據(jù)壓縮。
在一個(gè)實(shí)施例中,可以將所述分割字符串集合保存為字符串?dāng)?shù)組并結(jié)合所述第一前綴樹(shù)來(lái)保存所述第一字符串集合。
在另一個(gè)實(shí)施例中,可以將所述分割字符串集合作為第二個(gè)字符串集合,通過(guò)類(lèi)似于步驟s901和s902中的操作來(lái)創(chuàng)建第二前綴樹(shù)和第二字符串子集,以保存所述分割字符串集合,從而在整體上基于由第一前綴樹(shù)和第二前綴樹(shù)組成的嵌套結(jié)構(gòu)以及第二字符串子集來(lái)保存所述第一字符串集合。
在另一個(gè)實(shí)施例中,可以迭代地執(zhí)行步驟s901-s904中的操作,以創(chuàng)建具有多個(gè)前綴樹(shù)的多層嵌套結(jié)構(gòu),從而在整體上基于該嵌套結(jié)構(gòu)以及對(duì)應(yīng)的內(nèi)層字符串集合來(lái)保存所述第一字符串集合。
以下繼續(xù)結(jié)合圖6中的示例性字符串集合進(jìn)行描述。在這個(gè)例子中,通過(guò)上述步驟s901和s902得到的外層壓縮前綴樹(shù)1依然如圖7所示。然后通過(guò)上述步驟s903對(duì)壓縮前綴樹(shù)1中的長(zhǎng)字符串進(jìn)行分割。這里,由于字符串中包含有作為分隔符的tab字符和空格,因此可以以這些分隔符作為分割標(biāo)記,對(duì)長(zhǎng)字符串進(jìn)行分割。所得到的分割字符串集合如圖10中的表格所示,其中,切分后的字符串“g”因?yàn)槭菃蝹€(gè)字符串,所以不包括在分割字符串集合中。然后,在一個(gè)實(shí)施例中,通過(guò)上述步驟s904,基于分割字符串集合來(lái)創(chuàng)建第二層前綴樹(shù),如圖11所示。從圖11中可以發(fā)現(xiàn),與不進(jìn)行分割操作相比,通過(guò)對(duì)壓縮邊上的字符串進(jìn)行分割,可以在分割后的字符串之間產(chǎn)生更多的相同前綴,因此在進(jìn)行前綴樹(shù)嵌套操作時(shí),更有效地去除了字符串之間的冗余,進(jìn)一步改善了空間利用效率。
另外,為了能夠恢復(fù)分割前的子字符串,可以將前綴樹(shù)中的對(duì)應(yīng)結(jié)點(diǎn)進(jìn)行關(guān)聯(lián),例如,可以在壓縮前綴樹(shù)1中的各個(gè)相應(yīng)的結(jié)點(diǎn)處保存指向壓縮前綴樹(shù)2中對(duì)應(yīng)的結(jié)點(diǎn)的指針,其中,壓縮前綴樹(shù)2中的結(jié)點(diǎn)關(guān)聯(lián)于對(duì)應(yīng)的字符串子集或分割字符串集合中的字符串。
接著上面這個(gè)例子,在得到壓縮前綴樹(shù)2后,如果壓縮邊上的字符串之間依然存在冗余,則可以繼續(xù)通過(guò)以上各個(gè)步驟對(duì)該壓縮前綴樹(shù)執(zhí)行嵌套操作,以得到壓縮前綴樹(shù)3。在這個(gè)例子中,由于url經(jīng)常具有相同的后綴,因此可以先對(duì)壓縮邊上的子字符串進(jìn)行翻轉(zhuǎn)操作,使后綴變?yōu)榍熬Y,然后再生成字符串的子集。翻轉(zhuǎn)后得到的字符串子集如圖12中的表格所示,通過(guò)翻轉(zhuǎn)操作字符串之間具有了更多的相同前綴,并因此可以實(shí)現(xiàn)進(jìn)一步地壓縮。所生成的壓縮前綴樹(shù)3如圖13所示。
本領(lǐng)域技術(shù)人員可以理解,以上結(jié)合由搜索詞和url列表組成的字符串進(jìn)行的描述僅僅是示例性的,本發(fā)明中提出的上述技術(shù)方案還可以應(yīng)用于其他場(chǎng)景并保存具有不同特征的數(shù)據(jù)。舉例而言,本發(fā)明還可以用于對(duì)即時(shí)通訊工具中的聊天記錄進(jìn)行高效保存,或者對(duì)新聞、書(shū)評(píng)、維基百科等網(wǎng)頁(yè)文本內(nèi)容進(jìn)行高效保存。
另外,本領(lǐng)域技術(shù)人員還可以理解,根據(jù)本發(fā)明所創(chuàng)建的各個(gè)前綴樹(shù)(例如,patricia型前綴樹(shù))均可以采用louds表達(dá)方式實(shí)現(xiàn)為louds型前綴樹(shù),從而通過(guò)其所支持的rank和select操作高效地實(shí)現(xiàn)對(duì)字符串的正向搜索和反向搜索。
在為原始字符串集合創(chuàng)建前綴樹(shù)之后,所面臨的另一個(gè)問(wèn)題如何對(duì)最終得到的字符串子集進(jìn)行高效保存。在本發(fā)明提出的技術(shù)方案中,可以利用集合中各個(gè)字符串之間的冗余來(lái)創(chuàng)建一個(gè)字符串?dāng)?shù)組,然后通過(guò)一個(gè)偏移量(offset)和一個(gè)長(zhǎng)度值(length)在所創(chuàng)建的字符串?dāng)?shù)組中表示對(duì)應(yīng)的字符串。
圖14和圖15示出了采用所提出的方法來(lái)保存一個(gè)具有20個(gè)字符串的集合的實(shí)例。具體地,圖14示出了所創(chuàng)建的字符串?dāng)?shù)組,其長(zhǎng)度為23個(gè)字節(jié)并且數(shù)組中的每個(gè)字符均順序地具有對(duì)應(yīng)的偏移量0-22。進(jìn)一步地,圖15中的表格示出了如何使用所創(chuàng)建的數(shù)組來(lái)表示集合中的20個(gè)字符串:每個(gè)字符串對(duì)應(yīng)的偏移量標(biāo)識(shí)了該字符串在字符串?dāng)?shù)組的起始位置,然后根據(jù)對(duì)應(yīng)的長(zhǎng)度值在數(shù)組中讀取對(duì)應(yīng)數(shù)目個(gè)字符,就可以獲得對(duì)應(yīng)的字符串。
通過(guò)這種方式可以顯著提高字符串集合的存儲(chǔ)效率。如果采用傳統(tǒng)存儲(chǔ)方式,對(duì)于每個(gè)字符串,均需要與該字符串中的字符數(shù)相等的字節(jié)數(shù)來(lái)存儲(chǔ)這個(gè)字符串(例如,需要8個(gè)字節(jié)來(lái)存儲(chǔ)computer),此外還需要一個(gè)額外的字節(jié)來(lái)存儲(chǔ)這個(gè)字符串的長(zhǎng)度。因此,在圖15所示的例子中,傳統(tǒng)存儲(chǔ)方式一共需要169(149+20)個(gè)字節(jié)來(lái)保存這個(gè)字符串集合。對(duì)比而言,通過(guò)本發(fā)明所提出的方法,即使針對(duì)每個(gè)字符串使用二個(gè)字節(jié)來(lái)分別表示偏移量和長(zhǎng)度,那么也僅僅需要63(23+20+20)個(gè)字節(jié)就可以保存這個(gè)字符串集合。另外,如果采用比特方式對(duì)偏移量和長(zhǎng)度進(jìn)行編碼,則可以進(jìn)一步節(jié)省用于表達(dá)每個(gè)字符串的存儲(chǔ)空間。
類(lèi)似地,在上文結(jié)合搜索詞和url列表描述的例子中,可以通過(guò)所提出的方式來(lái)存儲(chǔ)圖13所示的內(nèi)層前綴樹(shù)中由各個(gè)壓縮邊對(duì)應(yīng)的字符串組成的集合。
圖16示出了根據(jù)本發(fā)明的一個(gè)實(shí)施例的數(shù)據(jù)壓縮系統(tǒng)的框圖。在一個(gè)實(shí)施例中,所述數(shù)據(jù)壓縮系統(tǒng)包括:前綴樹(shù)創(chuàng)建單元(201),其為第一字符串集合創(chuàng)建第一前綴樹(shù),其中所述第一字符串集合包括多個(gè)原始字符串,其中前綴樹(shù)由父-子結(jié)點(diǎn)關(guān)系連接的多個(gè)結(jié)點(diǎn)構(gòu)成,前綴樹(shù)的每條邊表示包含至少一個(gè)字符的字符串,該字符串對(duì)應(yīng)于從該條邊的父結(jié)點(diǎn)到子結(jié)點(diǎn)的狀態(tài)轉(zhuǎn)移,其中把所述第一前綴樹(shù)中的邊所對(duì)應(yīng)的、長(zhǎng)度至少為2的字符串作為第一字符串子集;判定/分割單元(202),當(dāng)所述第一字符串子集中的任一字符串滿足預(yù)定條件時(shí),其將該字符串分割為二個(gè)或多個(gè)字符串片段,所述字符串片段與所述第一字符串子集中未被分割的字符串一起形成分割字符串集合;分割字符串保存單元(203),其保存所述分割字符串集合;前綴樹(shù)保存單元(204),其保存所述第一前綴樹(shù)。
進(jìn)一步地,所述判定/分割單元(202)可以把所述第一字符串子集中的字符串所包含的預(yù)定符號(hào)作為分割標(biāo)記符,基于分割標(biāo)記符將所述字符串分割為二個(gè)或更多個(gè)分割字符串。
進(jìn)一步地,所述判定/分割單元(202)可以把所述第一字符串子集中的字符串與預(yù)定字符串庫(kù)進(jìn)行匹配以尋找所述字符串中的匹配片段,并且將所述字符串分割為盡量長(zhǎng)的與所述匹配片段相同的字符串片段。
在另一個(gè)實(shí)施例中,所述分割字符串保存單元(203)將所述分割字符串集合作為第二字符串集合提供給所述前綴樹(shù)創(chuàng)建單元(201),以創(chuàng)建第二前綴樹(shù)和第二字符串子集;所述分割字符串保存單元(203)保存所述第二字符串子集;所述前綴樹(shù)保存單元(204)保存所述第二前綴樹(shù)。
進(jìn)一步地,所述前綴樹(shù)保存單元(204)可以將所述第一前綴樹(shù)的相應(yīng)結(jié)點(diǎn)關(guān)聯(lián)到所述第二前綴樹(shù)的對(duì)應(yīng)結(jié)點(diǎn)。
進(jìn)一步地,所述數(shù)據(jù)壓縮系統(tǒng)還包括:字符串?dāng)?shù)組保存單元(205),其把所述第二字符串子集保存為字符串?dāng)?shù)組,其中在所述字符串?dāng)?shù)組中,所述第二字符串子集中的各個(gè)字符串通過(guò)對(duì)應(yīng)的偏移量和長(zhǎng)度來(lái)表示。
在另一個(gè)實(shí)施例中,所述數(shù)據(jù)壓縮系統(tǒng)還包括:原始數(shù)據(jù)提供單元(100),其將與所述第一字符串集合關(guān)聯(lián)的原始數(shù)據(jù)提供給所述前綴樹(shù)創(chuàng)建單元(201)。
在另一個(gè)實(shí)施例中,所述數(shù)據(jù)壓縮系統(tǒng)還包括:壓縮數(shù)據(jù)提供單元(300),其基于來(lái)自所述分割字符串保存單元(203)、前綴樹(shù)保存單元(204)、字符串?dāng)?shù)組保存單元(205)的數(shù)據(jù)來(lái)提供壓縮數(shù)據(jù)。
關(guān)于圖16所示裝置的其他實(shí)施例,可以參考圖9所示的方法實(shí)施例,在此不再贅述。
需要說(shuō)明的是,圖16所示的結(jié)構(gòu)框圖僅僅為了示例的目的而示出的,并非是對(duì)本發(fā)明的限制。在一些情況下,可以根據(jù)需要添加或者減少其中的一些模塊。并且請(qǐng)注意,本發(fā)明可以有效地實(shí)現(xiàn)于包括服務(wù)器、pc、移動(dòng)計(jì)算設(shè)備在內(nèi)的各種電子設(shè)備中,這些電子設(shè)備的具體結(jié)構(gòu)框圖在本說(shuō)明書(shū)中不再贅述,本領(lǐng)域技術(shù)人員應(yīng)該可以清楚地了解對(duì)應(yīng)的實(shí)現(xiàn)方式。
本領(lǐng)域技術(shù)人員應(yīng)當(dāng)理解,結(jié)合本發(fā)明公開(kāi)的各個(gè)實(shí)施例所描述的各種示例性的方法步驟和系統(tǒng)模塊、單元、部件等均可以實(shí)現(xiàn)成電子硬件、計(jì)算機(jī)軟件或二者的組合。為了清楚地表示硬件和軟件的可交換性,上文中各種示例性的步驟和單元均圍繞其功能進(jìn)行了總體描述。至于這種功能是實(shí)現(xiàn)成硬件還是實(shí)現(xiàn)成軟件,則取決于特定的應(yīng)用和對(duì)整個(gè)系統(tǒng)所施加的設(shè)計(jì)約束條件。本領(lǐng)域技術(shù)人員可以針對(duì)每個(gè)特定應(yīng)用,以變通的方式實(shí)現(xiàn)所描述的功能,但是,這種實(shí)現(xiàn)決策不應(yīng)被解釋為偏離了本發(fā)明的發(fā)明構(gòu)思。
本發(fā)明說(shuō)明書(shū)中使用的“示例/示例性”表示用作例子、例證或說(shuō)明。除非明確表明,否則說(shuō)明書(shū)中被描述為“示例性”的任何技術(shù)方案不應(yīng)被解釋為比其它技術(shù)方案更優(yōu)選或更具優(yōu)勢(shì)。
本發(fā)明提供了對(duì)所公開(kāi)的技術(shù)內(nèi)容的詳細(xì)描述,以使本領(lǐng)域技術(shù)人員能夠?qū)崿F(xiàn)或使用本發(fā)明。對(duì)于本領(lǐng)域技術(shù)人員而言,對(duì)這些技術(shù)內(nèi)容的很多修改和變形都是顯而易見(jiàn)的,并且本發(fā)明所定義的總體原理也可以在不脫離本發(fā)明的精神或范圍的基礎(chǔ)上適用于其它實(shí)施例。因此,本發(fā)明并不限于上文所示的具體實(shí)施方式,而是應(yīng)與符合本發(fā)明公開(kāi)的發(fā)明構(gòu)思的最廣范圍相一致。