大型比较任务的估计



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

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

我试过朴素的算法,我已经改进了好几天了,我似乎不能在几个小时内完成。

到目前为止我做了什么:

CPU:

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

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

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

虚拟内存:

我根据可用的空闲内存(System.freeMemory() -手动指定后约2GB)确定缓冲区大小,以防止抖动,并且我已经解决了每个文件保存的信息之间的合理权衡

算法:

在对文件结构进行静态分析后,我尝试只比较可疑位置的字节子集(JAR文件,我没有进入字节码,因为我不知道如何从字节码推断相关性-我只比较"classes.dex")。


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

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

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


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

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

如果你有"Dog", "Dad", "Dod", "Dog",你要以这样的结尾

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

因为字符串是固定长度的n,你将在每个级别i最多有256^i个节点,所以总数将是256^0 + 256^1 +…+ 256^n(这是一个上限)节点

最新更新