以有限个字节序列连缀而成的数据流,怎样较高效地用字典算法对其压缩?
有一串数据流以下述方式构成:在N个(N有限但未知,数量级少则几十,多则一两百)长度都等于L(L已知,数量级在K到100K之间)的字节序列中,每次随机取出其中一个(注意:是随机但不是等概率地出现,这一点很重要),加在这串数据的后面。
现在需要在内存和处理器性能都较为受限的条件下,用一种简单的方法对这串数据进行实时地压缩,就是说一边读取输入的数据流,一边输出压缩后的结果数据流。大致类似于字典算法:维护一个已知序列的索引表,每当读到一个在表中不存在的序列,则向表中添加该序列,并赋予一个新的索引值,同时将该序列输出到结果流;以后若读到的序列在表中存在,则直接将对应的索引号输出到结果流。
关键的难点就在于如何在索引表中查找给定的序列(或判定为不存在于表中):序列的长度L比较大,若每次只是简单地将读到的序列与已有表中所有已知序列作比较从而找到与其完全相同的序列的话,显然运算量太大。用什么样的算法可以较为高效地实现上述的实时压缩呢?
一种明显的思路是尽可能“早”地把与当前读到序列不同的序列排除,因为虽然为判断“相等”所进行的全长度比较是不可能省略的,但判断“不等”则只需发现一个字节不等就可以了。 如果当前读到的序列在已知序列中不存在,则尽早地将已知序列全部排除,就能尽早地知道这是一个新序列,然后将其添进表中;如果当前读到的序列在已知序列中存在,则尽量快地排除掉那些与当前序列不同的,就能只剩下一个可能与之相同的已知序列,再进行逐字节的比较,运算复杂度就只是O(L)而已了。总之,尽可能“快”地把与当前序列不等的序列排除在候选范围之外,是这个算法的关键。问题是,怎样做?
我的想法是,选取若干个取样位置,每个取样位置均满足条件:表中已有的序列在该位置上的值不全相同(或者说至少有一个是与其它序列不同的),用这些位置上各序列的取值来构造一个树,使得通过逐个判定这些位置上的值,逐步缩小范围。问题就转化为怎样选取这些判定位置及判定的顺序?它们的选择显然直接影响到每处理一个序列平均所需要判定次数。并且判定位置的选取和判定树的生成肯定不是一次性的,而是应该随着处理过程的进行不断地调整。
为此求教于众大侠,望指点迷津!