我应该使用哪种集合类型来存储一堆哈希值?

时间:2013-05-29 11:32:13

标签: c# collections

我有一堆长弦,我必须操纵。它们可以一次又一次地出现,如果它们出现两次我想忽略它们。我认为最好的方法是对字符串进行散列并将哈希列表存储在某种有序列表中,并且查找时间很快,以便每当我的数据集向我发送新字符串时我都可以进行比较。

要求:

  • 能够将项目(哈希)添加到我的收藏中
  • 能够(快速)检查特定哈希是否已经在集合中。
  • 内存不太密集。我最终可能会得到大约100,000个哈希值。

如果这有任何不同,我不需要倒退(键 - >值)。

有关哪种.NET数据类型最有效的建议?

2 个答案:

答案 0 :(得分:8)

  

我认为最好的方法是对字符串进行散列并将哈希列表存储在某种有序列表中,并且查找时间很快,以便每当我的数据集向我提交一个新字符串时我都可以进行比较。 / p>

不,不要那样做。有两个原因:

  • 哈希仅告诉您两个值可能是否相同;他们不会告诉你他们 是否相同。
  • 你已经做了很多已经为你做过的工作。

基本上,你应该保留一个HashSet<String>。这应该没问题,快速查找,你不需要自己实现它。

缺点是你最终将所有字符串保留在内存中。如果这是一个问题,那么你需要制定一个替代策略......这可能最终只能保留内存中的哈希值。确切的细节可能取决于字符串的来源,以及如果你出现误报会导致什么样的问题。例如,您可以将每个字符串的MD5哈希保留为“优于hashCode”哈希 - 但这仍然允许攻击者向您展示具有相同哈希的另一个字符串。那是问题吗?如果是这样,更安全的哈希算法(例如SHA-256)可能会有所帮助。它仍然不会保证你最终会得到不同字符串的不同字符串。

如果你真的想确定,你需要将哈希保留在内存中但是保留实际的字符串数据(到磁盘或数据库) - 然后当你有一个可能的匹配(因为您之前看到过相同的哈希),您需要将存储的字符串与新字符串进行比较。

如果要将哈希值存储在内存中,最佳方法将取决于您使用的哈希值。例如,对于64位哈希,您可以使用每个哈希Long并将其保留在HashSet<Long>中。对于更长的哈希,您需要一个可以轻松比较的对象等。此时,我建议您查看Guava及其HashCode类以及{{3}中的工厂方法(自Guava v16后不推荐使用)。

答案 1 :(得分:2)

使用一套。

ISet<T>接口由例如HashSet<T>

预期

AddContains为O(1),除非你的散列函数非常差,否则最坏的情况是O(n)。