1

我有一个来自大学的编程任务,需要通过逐字节比较数百个文件(好文件和坏文件,小于 1 兆字节)来查找恒定长度的共享字符串。

假设我要对比较进行全面覆盖,并且实际上将每个文件与其他文件进行比较,是否有可能在几分钟内真正完成这项任务?

我已经尝试了简单的算法,并且我已经改进了几天,而且我似乎无法在几个小时内下降。

到目前为止我做了什么:

中央处理器:

我在本地对不同的比较和缓冲区大小进行了基准测试,以查看最适合我的需求。

我不保留签名本身,只保留对它的引用(通过具有相同文件大小的布尔数组 - 也有助于我不再比较已被排除的索引)。

我目前正在将可调用的比较任务安装到系统中,希望它不会产生太多的开销或同步问题。

虚拟内存:

我正在根据可用的可用内存(System.freeMemory()手动指定后大约 2GB)来确定缓冲区大小,以防止颠簸,并且我已经决定在每个文件保存的信息之间进行合理的(在我看来)权衡

算法:

在静态分析文件结构(JAR 文件,我没有进入字节码,因为我不知道如何从字节码推断相关性 - 我只比较“classes.dex”)。


鉴于这一定是一项常见任务,我是否遗漏了一些非常明显的东西?有人告诉我散列签名可以更快,但我怀疑这比等待比较结束并稍后通过引用存储它们要快(一旦比较本身是瓶颈,这将非常快) . 对我来说,散列似乎是一个巨大的虚拟机占用风险。

被告知这应该在“合理的时间内”运行,目的是找到文件(或接近它)的最佳(最小)超集(涵盖大多数坏文件和没有好文件)。在我听了一些声称已经完成它的人之后,我似乎已经离开了。

如果需要更多信息,请询问,我会将其编辑到帖子中。


我打算使用Trie 的这个实现,以防我忘记更新它,我希望遇到这个问题的你可以利用它(或这个项目中的其他人)来满足你的需要!

4

1 回答 1

1

如果你想覆盖所有字符串,你所追求的是一个trie. 这是一棵树,其中每个节点都是您的字符串之一的一个字节。最后一个节点将报告字符串出现的次数。

如果你有“Dog”、“Dad”、“Dod”、“Dog”,你会以类似的结尾

 D
 | -------
 |       |
 a       o-------
 |       |      |
 |       |      |
 d(1)    d(1)   g(2)

由于字符串的长度是固定n的,因此每个级别 i 最多有 256^i 个节点,因此总数为 256^0 + 256^1 + ... + 256^n (这是一个上限)节点.

于 2013-06-18T09:58:03.760 回答