检测随机有序输入的变化(散列函数?)

时间:2008-09-15 16:01:02

标签: java multithreading hash

我正在阅读可以按任何顺序排列的文本行。问题是输出实际上可能与先前的输出相同。如何在不先对输出进行排序的情况下检测到这一点?

是否有某种哈希函数可以采用相同的输入,但是以任何顺序,仍然会产生相同的结果?

7 个答案:

答案 0 :(得分:3)

最简单的方法似乎是在路上散列每一行,存储散列和原始数据,然后将每个新散列与您现有散列的集合进行比较。如果你得到肯定,你可以比较实际数据,以确保它不是误报 - 虽然这将是非常罕见的,你可以使用更快的哈希算法,如MD5或CRC(而不是像SHA,这是速度较慢但不太可能发生碰撞),只是这样快速,然后在遇到命中时比较实际数据。

答案 1 :(得分:0)

所以你有像

这样的输入
A B C D
D E F G
C B A D

你需要检测第一行和第三行是否相同?

答案 2 :(得分:0)

如果你想知道两个文件是否包含相同的行集,但顺序不同,你可以分别在每一行上使用常规散列函数,然后将它们与排序无关紧要的函数组合,喜欢加法。

答案 3 :(得分:0)

如果行很长,你可以保留每行的哈希列表 - 对它们进行排序并与之前的输出进行比较。

如果您不需要100%傻瓜式解决方案,您可以将每行的哈希值存储在Bloom过滤器中(在维基百科上查找)并在处理结束时比较Bloom过滤器。这可以给你误报(即你认为你有相同的输出,但实际上并不相同),但你可以通过调整Bloom过滤器的大小调整错误率...

答案 4 :(得分:0)

如果将每个字符的ASCII值相加,无论顺序如何,都会得到相同的结果。

(这可能有点过于简化,但也许它会给你一个想法。 有关有趣的背景故事,请参阅编程珍珠,第2.8节。)

答案 5 :(得分:0)

任何基于散列的方法都可能产生错误的结果,因为多个字符串可以产生相同的散列。 (这不太可能,但它是可能的。)对于添加哈希值的建议尤其如此,因为您实际上将采用哈希值的特别错误的哈希值。

只有在您错过更改或发现不存在更改的情况并不重要时,才应尝试哈希方法。

最准确的方法是使用行字符串作为键来保存Map,并将每个字符串的计数存储为值。 (如果每个字符串只能出现一次,则不需要计数。)计算预期的行数。复制此集合以检查传入的行,减少每行的计数。

  • 如果您遇到零计数的行(或根本没有地图条目),您会看到一条您没想到的行。
  • 如果您以地图中剩余的非零条目结束此操作,则您没有看到预期的内容。

答案 6 :(得分:0)

问题规范有点受限。

据我所知,你希望看到几个字符串是否包含相同的元素,无论顺序如何。

例如:

A B C
C B A

是一样的。

这样做的方法是创建一组值然后比较集合。要创建集合,请执行以下操作:

HashSet set = new HashSet();
foreach (item : string) {
   set.add(item);
}

然后只需通过运行其中一个集合并与其他集合进行比较来比较集合的内容。对于排序示例,执行时间将为O(N)而不是O(NlogN)

相关问题