我有一个二进制文件,其中一个记录重复多次。该文件仅包含此记录,但可能会重复多次。
我不知道记录的大小。提取记录并知道记录重复次数的最佳算法是什么。
例如,假设我有一个以十六进制表示以下内存表示的文件。 (忽略文件头和所有东西)
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完成,但还有其他任何更好,更有效的方法。
答案 0 :(得分:1)
一种可能性是获取文件的大小并将其考虑在内。例如,如果文件大小为1280,那么您知道记录大小是以下之一:
1,2,4,5,8,10,16,20,32,40,64,80,128,160,256,320,640,1280
然后,您可以测试每个假设,直到找到匹配或耗尽可能性。
当然,这假定文件未被截断或以其他方式损坏。
这可能不是最有效的方法,但它可以快速编写代码并且可以非常快速地完成您的工作。这取决于您的文件有多大以及您想要执行此操作的频率。有时蛮力解决方案是正确的解决方案,即使它不是最好的解决方案。溶液
答案 1 :(得分:0)
答案 2 :(得分:0)
l
为1 l
的块来检查您的假设是否正确。一找到不匹配就立即停止。l
的块的下一个匹配项。这为您提供了另一个候选记录长度。如果下一个匹配块从索引i
开始(基于零),请设置l = i
并转到步骤2. 如果您知道始终存在解决方案,则可能会加快步骤2的速度。如果您检查了50%的数据,则可以停止。
注意:此答案假设您正在寻找最短的记录。如果您的所有字节都是FF,那么可以找到许多其他解决方案而不是l=1
(例如只有一条大记录)。
示例:以3F的大小为1的记录开头。然后通过检查所有后续字节是否也是3F来检查这是否是完整记录。您可以使用下一个字节停止,因为它不同。现在寻找下一个3F。它发生在索引3(基于零)。现在您知道您的记录长度至少为3个字节。假设您的记录长度为3个字节。检查所有后续三个字节块是否与您的记录匹配。完成!