Algo在文件

时间:2015-12-22 19:09:06

标签: algorithm

我有一个二进制文件,其中一个记录重复多次。该文件仅包含此记录,但可能会重复多次。

我不知道记录的大小。提取记录并知道记录重复次数的最佳算法是什么。

例如,假设我有一个以十六进制表示以下内存表示的文件。 (忽略文件头和所有东西)

  

3F 5C BA 3F 5C BA 3F 5C BA 3F 5C BA 3F 5C BA 3F 5C BA 3F 5C BA 3F 5C   BA 3F 5C BA 3F 5C BA 3F 5C BA 3F 5C BA 3F 5C BA 3F 5C BA 3F 5C BA 3F   5C BA

所以这里我的记录是3F 5C BA,3字节,在这里重复15次。

如何获取这些值(记录的大小和重复的次数)。可以使用Rabin Karp完成,但还有其他任何更好,更有效的方法。

3 个答案:

答案 0 :(得分:1)

一种可能性是获取文件的大小并将其考虑在内。例如,如果文件大小为1280,那么您知道记录大小是以下之一:

1,2,4,5,8,10,16,20,32,40,64,80,128,160,256,320,640,1280

然后,您可以测试每个假设,直到找到匹配或耗尽可能性。

当然,这假定文件未被截断或以其他方式损坏。

这可能不是最有效的方法,但它可以快速编写代码并且可以非常快速地完成您的工作。这取决于您的文件有多大以及您想要执行此操作的频率。有时蛮力解决方案是正确的解决方案,即使它不是最好的解决方案。溶液

答案 1 :(得分:0)

您可以查看后缀树,可以将字符串的所有后缀插入到后缀树中,并计算某个子字符串出现的次数,然后进行树遍历并找到答案。

enter image description here

答案 2 :(得分:0)

  1. 首先假设记录的长度l为1
  2. 通过比较所有后续大小l的块来检查您的假设是否正确。一找到不匹配就立即停止。
  3. 如果未找到不匹配,则表示您已完成。 RETURN。
  4. 搜索长度为l的块的下一个匹配项。这为您提供了另一个候选记录长度。如果下一个匹配块从索引i开始(基于零),请设置l = i并转到步骤2.
  5. 如果您知道始终存在解决方案,则可能会加快步骤2的速度。如果您检查了50%的数据,则可以停止。

    注意:此答案假设您正在寻找最短的记录。如果您的所有字节都是FF,那么可以找到许多其他解决方案而不是l=1(例如只有一条大记录)。

    示例:以3F的大小为1的记录开头。然后通过检查所有后续字节是否也是3F来检查这是否是完整记录。您可以使用下一个字节停止,因为它不同。现在寻找下一个3F。它发生在索引3(基于零)。现在您知道您的记录长度至少为3个字节。假设您的记录长度为3个字节。检查所有后续三个字节块是否与您的记录匹配。完成!