計算機演算法:資料壓縮之字首編碼(5)

湯曉發表於2014-11-20

概述

字首編碼,有時也被稱為前向編碼,是另一個通過移除冗餘資料來降低資料量的演算法。思想非常簡單,但演算法實現比較困難。要了解原因,首先我們來看一看它的原理。

請看下面的字典。

為了不使用純文字儲存這些單詞或者在網路上傳輸,我們可以用字首編碼進行壓縮(編碼)。

很明顯,每一個單詞都以表中的第一個單詞“use”為字首。所以我們很容易將它們壓縮成下面的陣列。

顯然這並不是最佳的壓縮結果,在不僅僅使用第一個詞作為字首的情況下,我們可以更進一步壓縮。

此時的壓縮更好,好訊息是解碼是一個相對簡單的過程。但棘手的部分在於壓縮本身。問題是選擇合適的字首非常困難。第一個例程的字首選擇很簡單,但事實上,大多時候資料很混亂。的確,對於隨機產生的資料壓縮過程將非常困難,演算法過程不僅很慢,而且難以實現。

好的方面是,如果我們事先知道資料的格式,該演算法可以用於多種情況。那麼,讓我們看看下面三個例子,該演算法可能會很方便。

應用

以下是三個字首編碼的例子。前面我說隨機資料的壓縮過程會很難,如果你事先知道輸入資料的格式,這將會是一個很好的練習。

日期和時間字首

我們通常會忽略年份的前兩個數字,例如我們通常不會寫1995或1996,而是使用更短的——‘95’和‘96’。這樣年份就被編碼成更短的字串。

問題在於輸入流發生很小的變動,解碼就會出錯。如果我們加上21世紀的年份,我們將失去資料的唯一性。

此時,解碼器肯會將最後兩個數值解碼成(1911, 1912),因為“19”被認為是字首。所以,我們事先必須知道字首與每一個數值絕對平等。如果沒有編碼格式,必須不同。例如我們可以使用一些特殊標識和字首一起編碼。

一旦解碼器讀到#字元,它就知道下面的數為字首。

事實上,這種方法可用於日期和時間格式的編碼。假設我們有一些日期時間值,而且我們知道所有資料都是在同一天。

顯然,我們可以忽略這些字串的時間部分,僅傳送(儲存)時間。當然,我們必須確定所有的這些數值都是在同一天。如果不是,我們可以使用上例中的方法。

電話號碼

電話號碼是字首編碼的典型應用。不僅僅是國際程式碼,行動網路運營商的電話號碼也使用字首編碼。如果我們要傳輸電話號碼,假設是英國的,我們可以用一些更短的東西替換開頭的“+44”。

如果你要給移動裝置編寫電話簿,你可以通過字首編碼壓縮資料,節省部分空間,這樣使用者將擁有更多空間,也可以在手機上儲存更多電話號碼。

電話號碼字首也適用於資料庫標準化。這樣你可以將它們儲存在單獨的資料庫表中,不用電話簿中唯一的號碼。

地理座標

對於我之前帖子中使用的例子,可以在一定範圍內去掉通用字首來傳送地理座標。的確,在必須傳送大量座標到地圖應用時,你可以預期這些標記在一定範圍內彼此間相當靠近。

在一定範圍內,可以預期這些標記都有相同的字首。

那些點的座標有共同的字首,就像下面地鐵站的例子一樣。

我們可以發現所有的地理座標點有相同的字首(40.76x, -73.98x),所以我們只需要傳送一次字首。

以上是字首編碼的三個例子,該演算法在傳輸均勻資料是非常有用。

字尾編碼

字尾編碼和字首編碼幾乎相同,區別在於編碼重複字尾。如下例,字尾編碼替換最後重複的字尾,這非常有用。

或者公司名稱。

這裡我們可以使用一些其他更短的東西來替換“Inc”。

相關文章