检测重复的线组

时间:2012-06-12 06:39:41

标签: algorithm compression

我有几兆字节的数据:

11  2  1
 4  3  1
11  2  1
 4  3  1
11  2  1
 4  3  1
18  3  2

我想通过添加“前n行重复m次”的行来压缩它。该算法应该读取行并延迟打印它们直到找到尽可能长的m * n,但是可以假设n <= 10。最好的方法是什么?

我在考虑只保留10个1..10前一行的数组和重复计数器,当新行进入时旋转数组内容并在新读取的行与任何最旧的行匹配时打印上述消息数组中,至少有一个数组填充了重复数据。

3 个答案:

答案 0 :(得分:1)

zip算法可以保持数据的可读性。他们只是创建重复元素的字典(例如,查看lempel - ziv)。 我认为算法的描述方式可能有问题。你的第二行与你的第一行不同,所以你怎么知道你应该将它们视为一个群体呢?你什么时候限制小组,然后开始新的小组? 你怎么知道

11 2 1
4 3 1

真的属于同一个群体吗?

我认为lempel ziv可以为你解决这个问题,包括所有可能的子集及其出现次数的字典。 在你的字典中,你将有子集,如

11 2 1
4 3 1
11 2 1

但是如果你知道重复的行将成对或三元组,你可以限制算法中的已检查子集,并将字符集中的子集保持在预期的长度。
这样最终你的字典将如下所示:

key          : count
11 2 1       : 3
4  3 1       : 3
11 2 1, 4 3 1: 3
18 3 2       : 1

当然,它需要更多的调整,但我认为这个算法应该是大方向

答案 1 :(得分:1)

“复制前m行重复m次”是“从j行开始复制k行”的限制版本。第一个是第二个,k = n * m,j = n。更一般的k,j版本是LZ77。 (虽然通常是字节而不是行。)

LZ77算法对此非常有用。 gzip,zlib等使用的哈希表方法快速且易于编码。首先,定义您认为值得的k(mink)的最小值,并定义您想要查找匹配的距离,即j(maxj)的最大值。然后构建一个maxj行的滑动窗口来搜索。

随着每一行的进入,更新仅依赖于最后一个mink行的哈希。在哈希表中查找与该哈希匹配的最后一行,然后将您的行直接与滑动窗口中的行进行比较,直到它们不匹配为止。然后,如果得到的长度是水貂或更多,则你有一个匹配,它由长度和距离(k和j)组成。

使用延迟匹配,您可以推迟匹配的发送,直到您处理下一行,这可能会给出更长的匹配。

答案 2 :(得分:0)

如果您认为您的文件是长字符串,那么我认为您的问题在于找到longest repeated substring