【问题标题】:Is the complexity of unordered_set::find predictable?unordered_set::find 的复杂性是可预测的吗?
【发布时间】:2014-07-20 02:30:47
【问题描述】:

在寻找适合我正在构建的应用程序的容器时,我遇到了unordered_set 的文档。鉴于我的应用程序通常只需要 insertfind 函数,这个类看起来相当有吸引力。但是,由于find 的摊销成本为 O(1),但最坏的情况为 O(n),我会稍微推迟一点——我会经常使用该函数,它可能会成就或破坏我的应用程序。是什么导致复杂性飙升?遇到 O(n) 搜索的可能性是否可预测?

【问题讨论】:

  • unordered_set 被实现为hash table。最坏的情况发生在大量元素不幸地散列到相同的值时(准确地说,当它们落入同一个散列桶时)。

标签: c++ c++11 data-structures complexity-theory


【解决方案1】:

_unordered_set_ 被实现为哈希表,也就是说,哈希表的常见实现之一是使用哈希桶的容器(例如:像向量)(即是同一桶中 unordered_set 元素的容器(例如:like list)

在 unordered_set 中插入元素时,会应用一个哈希函数,然后它会为您提供放置位置的存储桶。

可能有各种元素插入到同一个桶中,当你找到一个元素时,哈希函数就会应用,给你桶,你需要去寻找他们的元素,搜索你正在寻找的那个。

最坏的情况是所有元素都在同一个桶中结束(取决于用于将元素存储在同一个桶中的容器O(n)是当所有元素都在同一个桶中时搜索的最差运行时间) .

以同一桶结尾的元素的关键点是哈希函数(它有多好)和元素(可能暴露哈希函数的特定弱点)。

通常无法预测的元素,如果在您的情况下有足够的可预测性(您可以选择一个散列函数来均匀分布此类元素)。

为了加快搜索速度,关键是使用良好的哈希函数(均匀分布桶中的元素,并在需要时使用 rehash 增加桶大小(注意这个选项,哈希函数将应用于所有元素))。

我建议,如果这些元素的存储对您的应用程序非常重要,那么您可以使用尽可能接近生产数据的性能测试(并从那里做出决定),即 STL 中的容器以及更多的容器同一组(例如:associative 等)共享几乎相同的界面,很容易更换一个,而使用的代码几乎没有变化。

【讨论】:

  • 非常有意义。我正在从一个枚举类中进行散列,因此找到一个既高效又均匀分布元素的散列函数应该很简单。谢谢!
  • 如果键集是编译时常量,请考虑使用 gperf。 gnu.org/software/gperf 用于构建您提供的哈希函数。
  • 很酷的工具,@Solkar - 我会去看看。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-09
  • 1970-01-01
  • 2016-04-06
  • 2016-03-24
  • 2012-08-19
  • 2015-04-08
  • 1970-01-01
相关资源
最近更新 更多