检查数字是否在数字列表中的最快方法

时间:2011-03-09 13:58:42

标签: c++

我需要检查一个ID(一个长整数)是否在~10,000个ID的列表中。我需要在循环中执行大约10 ^ 9次,速度相对重要。使用c ++设置最快的方法吗?类似的东西:

set<long> myset;

// (Populate myset)

long id = 123456789;

if(myset.find(id) != myset.end()) {
     // id is in set
}

或者有更快的方法吗?

5 个答案:

答案 0 :(得分:17)

如果您的长度范围有限,最快的方法是位图(例如vector<bool>)。如果这不可行,则应尝试unordered_set(hash_set)。如果这种情况持续发生最坏情况,那么然后使用set

答案 1 :(得分:4)

嗯,取决于你如何生成数字和数量,使用std::vector可能会更快,对它进行排序(甚至可以在插入数字时对其进行排序),以及使用{ {3}}检查号码是否在那里。

通常情况下,套装可以正常使用,但需要权衡。向量具有较少的内存开销,并且由于所有数字都存储在连续的内存块中,因此在某些情况下它可能优于集合,但您必须对其进行测试。

答案 2 :(得分:1)

如果ID存在,您可以构建哈希表并检入O(1)。

答案 3 :(得分:0)

出于最佳意图,该标准决定vector<bool>应专门用作bitset。

bit-set足够快,你也可以选择std :: bitset,它是固定大小的,boost::dynamic_bitset的大小是运行时定义的,并且构建在{{1无论如何(它可能是关于使用什么整数类型的模板)。

没有必要进一步优化以节省一些麻烦,所以建议使用其中一种。

顺便说一句,我已经看到了一个“分散的”位图,如果值落在某个范围内,它会使用一个,否则它将使用树型查找。 (此技术也可用于Z表(正态分布CDF类型)功能,您可以在内存中“缓存”高达95%或99%的密度,并使用慢速计算极值(和我曾经不得不这样做。)

答案 4 :(得分:0)

如果你真的想把它推到顶端,你也可以选择使用两阶段方法。

  1. 使用布隆过滤器或类似的概率算法来确定该值是否明确不在集合中或“可能”集合中。
  2. 要查看步骤1是否产生误报,您需要执行更昂贵的第二阶段,仅针对那些未通过步骤1过滤掉的人。在您的许多(您提到的10 ^ 9)查询中,您应该做得更多快速(如果没有太多的查询被击中......)。
  3. 有关详细信息,请参阅http://en.wikipedia.org/wiki/Bloom_filter。 另请参阅:Search algorithm with minimum time complexity