计算机算法:数据压缩之前缀编码

来源:互联网 发布:js input type 编辑:程序博客网 时间:2024/05/16 10:08

概述


前缀编码,有时也被称为前向编码,是另一个通过移除冗余数据来降低数据量的算法。思想非常简单,但算法实现比较困难。要了解原因,首先我们来看一看它的原理。


请看下面的字典。


use

used

useful

usefully

usefulness

useless

uselessly

uselessness


为了不使用纯文本保存这些单词或者在网络上传输,我们可以用前缀编码进行压缩(编码)。



很明显,每一个单词都以表中的第一个单词“use”为前缀。所以我们很容易将它们压缩成下面的数组。


$data = array(

0 => 'use',

1 => '0d',

2 => '0ful',

3 => '0fully',

4 => '0less',

5 => '0lessly',

6 => '0lessness',

);


显然这并不是最佳的压缩结果,在不仅仅使用第一个词作为前缀的情况下,我们可以更进一步压缩。


$data = array(

0 => 'use',

1 => '0d',

2 => '0ful',

3 => '2ly',

4 => '0less',

5 => '4ly',

6 => '4ness',

);


此时的压缩更好,好消息是解码是一个相对简单的过程。但棘手的部分在于压缩本身。问题是选择合适的前缀非常困难。第一个例程的前缀选择很简单,但事实上,大多时候数据很混乱。的确,对于随机产生的数据压缩过程将非常困难,算法过程不仅很慢,而且难以实现。


好的方面是,如果我们事先知道数据的格式,该算法可以用于多种情况。那么,让我们看看下面三个例子,该算法可能会很方便。


应用


以下是三个前缀编码的例子。前面我说随机数据的压缩过程会很难,如果你事先知道输入数据的格式,这将会是一个很好的练习。


日期和时间前缀


我们通常会忽略年份的前两个数字,例如我们通常不会写1995或1996,而是使用更短的——‘95’和‘96’。这样年份就被编码成更短的字符串。


input:(1991,1992,1993,1994,1995,1996)

output:(91,92,93,94,95,96)


问题在于输入流发生很小的变动,解码就会出错。如果我们加上21世纪的年份,我们将失去数据的唯一性。


input:(1998,1992,1999,2011,2012)

output:(98,92,99,11,12)


此时,解码器肯会将最后两个数值解码成(1911, 1912),因为“19”被认为是前缀。所以,我们事先必须知道前缀与每一个数值绝对平等。如果没有编码格式,必须不同。例如我们可以使用一些特殊标识和前缀一起编码。


input:(1998,1992,1932,1924,2001,2012)

output:(#19, 98, 92, 32, 24, #20, 01, 12)


一旦解码器读到#字符,它就知道下面的数为前缀。


事实上,这种方法可用于日期和时间格式的编码。假设我们有一些日期时间值,而且我们知道所有数据都是在同一天。


2012-01-3115:33:45

2012-01-3116:12:11

2012-01-3117:32:35

2012-01-3118:54:34


显然,我们可以忽略这些字符串的时间部分,仅发送(保存)时间。当然,我们必须确定所有的这些数值都是在同一天。如果不是,我们可以使用上例中的方法。


电话号码


电话号码是前缀编码的典型应用。不仅仅是国际代码,移动网络运营商的电话号码也使用前缀编码。如果我们要传输电话号码,假设是英国的,我们可以用一些更短的东西替换开头的“+44”。


如果你要给移动设备编写电话簿,你可以通过前缀编码压缩数据,节省部分空间,这样用户将拥有更多空间,也可以在手机上存储更多电话号码。

电话号码前缀也适用于数据库标准化。这样你可以将它们存储在单独的数据库表中,不用电话簿中唯一的号码。


地理坐标


对于我之前帖子中使用的例子,可以在一定范围内去掉通用前缀来发送地理坐标。的确,在必须传送大量坐标到地图应用时,你可以预期这些标记在一定范围内彼此间相当靠近。


在一定范围内,可以预期这些标记都有相同的前缀。


那些点的坐标有共同的前缀,就像下面地铁站的例子一样。


LatLon(40.762959,-73.985989)

LatLon(40.761886,-73.983629)

LatLon(40.762861,-73.981612)

LatLon(40.764616,-73.98056)


我们可以发现所有的地理坐标点有相同的前缀(40.76x, -73.98x),所以我们只需要发送一次前缀。


Prefix:(40.76, -73.98)

Data:

LatLon(2959,5989)

LatLon(1886,3629)

LatLon(2861,1612)

LatLon(4616,056)


以上是前缀编码的三个例子,该算法在传输均匀数据是非常有用。


后缀编码


后缀编码和前缀编码几乎相同,区别在于编码重复后缀。如下例,后缀编码替换最后重复的后缀,这非常有用。


Johnson

Clarkson

Jackson


或者公司名称。


AppleInc.

GoogleInc.

Yahoo!Inc.


这里我们可以使用一些其他更短的东西来替换“Inc”。

编辑:www.erfeirizhi.com 二飞日志

0 0
原创粉丝点击