我有一个来自大学的编程任务,需要通过逐字节比较数百个文件(好文件和坏文件,小于一兆字节)来查找长度恒定的共享字符串。
假设我要完全覆盖比较,我实际上将每个文件与其他文件进行比较,是否可以在几分钟内实际完成此任务?
我已经尝试过天真的算法,而且我现在已经改进了好几天了,而且我似乎无法在几个小时内完成。
到目前为止我做了什么:
我在本地标记了不同的比较和缓冲区大小,以确定最适合我的需求。
我不保留签名本身,只是对它的引用(通过与文件大小相同的布尔数组 - 也有助于我不再比较已被排除的索引)。< / p>
我目前正在将可调用的比较任务安装到系统中,希望它不会产生太多的开销或同步问题。
我根据可用的可用内存确定缓冲区大小(System.freeMemory()
- 手动指定后大约2GB)以防止颠簸并且我已经确定了合理的(我认为)交易 - 每个文件保存的信息之间的关闭
在静态分析文件后,我尝试仅比较可疑位置的一部分字节。结构(JAR文件,我没有进入字节码,因为我不知道如何从字节码推断相关性 - 我只比较&#34; classes.dex&#34;)。
鉴于这必须是一项常见任务,我是否遗漏了一些非常明显的事情?我已经被告知散列签名可能会更快,但我怀疑它比等待比较结束并在以后通过引用存储它们更快(一旦比较本身,这是非常快的,是瓶颈,结束)。对我而言,哈希看起来像是一个巨大的虚拟机。
有人告诉我这应该在&#34;合理的时间内运行&#34;目标是找到文件(或接近它)的最佳(最小)超集(涵盖大多数坏文件和没有好文件)。在我听到一些声称已经完成它的人之后,我似乎已经离开了。
如果需要更多信息,请询问,然后我将其编辑到帖子中。
我打算使用this实现Trie,以防我忘记更新,我希望遇到此问题的人可以利用它(或此项目中的其他人)来满足您的需求!
答案 0 :(得分:1)
如果你想覆盖所有字符串,你所追求的是trie
。它是一棵树,每个节点都是一个字符串的字节。最后一个节点将报告String出现的次数。
如果您有“狗”,“爸爸”,“Dod”,“狗”,您会以
之类的结尾 D
| -------
| |
a o-------
| | |
| | |
d(1) d(1) g(2)
由于字符串具有固定长度n
,因此每个级别i将具有最多256 ^ i个节点,因此总数将为256 ^ 0 + 256 ^ 1 + ... + 256 ^ n (这是一个上限)节点。