【问题标题】:storing sets of integers to check if a certain set has already been mentioned存储整数集以检查是否已经提到了某个集合
【发布时间】:2012-07-14 14:20:48
【问题描述】:

我遇到了一个有趣的问题,我很想得到一些意见。

我有一个程序可以生成一组数字(基于一些预定义的条件)。每个集合最多包含 6 个数字,这些数字不必唯一,整数范围为 1 到 100)。

我想以某种方式存储创建的每个集合,以便我可以快速检查以前是否生成了具有完全相同数字(顺序无关紧要)的某个集合。

在这种情况下,速度是一个优先事项,因为在程序停止之前可能存储了多达 100k 组(可能更多,但大多数时间可能更少)!有人对我应该使用什么数据结构以及我应该如何解决这个问题有任何建议吗?

我目前拥有的是这样的:

在将每个集合存储到字符串的 HashSet 之前对其进行排序。字符串只是排序集中的每个数字,带有一些分隔符。

例如,集合 {4, 23, 67, 67, 71} 将被编码为字符串“4-23-67-67-71”并存储到 HashSet 中。然后对生成的每个新集合进行排序、编码并检查它是否存在于 HashSet 中。

谢谢!

【问题讨论】:

  • HashSet 是一个不错的选择,如果你有足够的记忆力。
  • 当它可以包含重复时,它不是一个集合。称它为 multiset 或 bag 。
  • 谢谢 Phillip,我不确定它的正确术语是什么。

标签: java set


【解决方案1】:

如果你把它分解成碎片,我觉得

  • 创建一个集合(生成 6 个数字、排序、字符串化)在 O(1) 中运行
  • 检查这个字符串是否存在于哈希集中是 O(1)
  • 插入哈希集是 O(1)

你这样做 n 次,这给你 O(n)。 这已经是最佳选择了,因为无论如何您都必须触摸每个元素一次:)

可能会遇到问题,具体取决于随机数的范围。 例如假设您只生成 1 和 1 之间的数字,那么显然只有一种可能的结果(“1-1-1-1-1-1”),并且从那里开始只会发生碰撞。但是,只要可能的序列数量远大于您生成的元素数量,我就没有问题。

一个提示:如果您事先知道生成的元素的数量,那么使用正确数量的元素(即new HashSet<String>( 100000 ) );

附言现在出现了其他答案,我想指出,虽然在微观层面上可能有改进的空间(即使用特定于语言的技巧),但您的整体方法无法改进。

【讨论】:

  • 感谢 Kritz,很高兴知道我走对了。我现在肯定会尝试一下,看看它的表现如何。我最担心的是排序,即使每个集合最多只有 6 个元素。
  • 好吧,它只有六个数字,所以应该很快。但如果这被证明是一个麻烦制造者,你可以看看这个 stackoverflow 问题:stackoverflow.com/questions/1866031/…
【解决方案2】:
  1. 创建一个类 SetOfIntegers
  2. 实现一个 hashCode() 方法,该方法将生成合理唯一的哈希值
  3. 使用 HashMap 存储您的元素,例如 put(hashValue,instance)
  4. 使用 containsKey(hashValue) 检查相同的 hashValue 是否已经存在

这样您就可以避免对集合进行排序和转换/格式化。

【讨论】:

  • 谢谢 Mazaneicha,我会看看 hashCode(),我以前从未真正重写过这个函数。您对根据我的问题范围定义不会发生冲突的哈希函数有什么建议吗?
  • 一如既往,StackOverflow 是你的朋友 :) 查看这篇文章 stackoverflow.com/questions/27581/… 祝你好运!
【解决方案3】:

只需为每个集合使用java.util.BitSet,使用 set(int bitIndex) 方法将整数添加到集合中,您无需对任何内容进行排序,并在添加新的 BitSet 之前检查 HashMap 是否已存在 BitSet它,它会非常快。如果速度很重要,请不要为此目的使用 value 和 toString 排序。

【讨论】:

  • 感谢 Christophe,这是一个非常有趣的解决方案。我快速浏览了 BitSet javadocs,我有一个问题。这种方法可以解释重复值吗?对于独特的集合来说,这似乎是一个很好的解决方案。
  • 是的,对不起,我完全错过了“不必是唯一的”部分(并且没有检查重复的 67 的样本值),所以它对你不起作用。然后使用int[] 数组、java.util.Arrays.sort(array)java.util.Arrays.equals(array1, array2) 静态方法,这是下一个最快/最容易做的事情。
猜你喜欢
  • 2016-07-20
  • 2023-03-13
  • 2012-03-10
  • 1970-01-01
  • 2017-02-05
  • 2022-01-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多