在滑动窗口中查找字符串匹配的算法

时间:2009-03-13 12:45:19

标签: algorithm compression zip gzip

像ZIP这样的文件压缩的​​核心步骤之一是使用先前解码的文本作为参考源。例如,编码流可能会说“接下来的219个输出字符与5161字节前的解码流中的字符相同”。这使您可以用3个字节左右表示219个字符。 (还有更多的ZIP,比如Huffman压缩,但我只是在谈论参考匹配。)

我的问题是字符串匹配算法的策略是什么。即使查看来自zlib的源代码,似乎也不能很好地描述压缩匹配算法。

问题可能表述为:给定一个文本块,比如它的30K和一个输入字符串,在30K文本中找到与输入正面完全匹配的最长引用字符串。“算法在迭代时必须是高效的,即30K的文本块将通过从前面删除一些字节并在后面添加新的字节并执行新的匹配来更新。

我对这些算法的讨论更感兴趣,源代码或库。 (zlib有非常好的来源!)我怀疑可能有几种方法有不同的权衡。

3 个答案:

答案 0 :(得分:3)

嗯,我注意到你详细讨论了这个问题,但是没有提到RFC 1951第4节中提供的信息(DEFLATE压缩数据格式的规范,即ZIP中使用的格式)这让我相信你可能错过了这个资源。

他们的基本方法是使用三字节序列作为键的链式哈希表。只要链不是空的,就会扫描沿着它的所有条目,a)消除错误的碰撞,b)消除太旧的匹配,c)从剩余的匹配中挑选最长的匹配。

(请注意,他们的建议是由专利因素决定的;可能是他们知道一种更有效的技术,但不能确定它不被某人的专利所覆盖。就我个人而言,我总是想知道为什么通过检查从输入数据的第二个字节,第三个字节等开始的三字节序列的匹配,并找出不匹配的匹配,找不到最长的匹配。即,如果你的传入数据是“ABCDEFG ...”并且您在偏移100,302和416处获得了“ABC”的哈希匹配,但您对“BCD”的唯一哈希匹配是偏移301,您知道除非您有两个完全重合的重叠哈希匹配 - 不太可能 - 那么302就是你最长的匹配。)

还要注意他们推荐的可选“延迟匹配”(具有讽刺意义的是做更多的工作):压缩器不是自动进行从输入数据的第一个字节开始的最长匹配,而是检查从下一个字节。如果您的输入数据是“ABCDE ...”并且您在滑动窗口中的唯一匹配是“ABC”和“BCDE”,那么最好将“A”编码为文字字节,将“BCDE”编码为一场比赛。

答案 1 :(得分:2)

我认为您正在描述Longest Common Substring Problem的修改版本。

答案 2 :(得分:1)

您可以查看LZMA Algorithm使用的7-zip的详细信息。 7-zip作者声称对zlib等人使用的算法进行了改进。