【问题标题】:Unordered_set iterator randomUnordered_set 迭代器随机
【发布时间】:2015-09-18 04:50:42
【问题描述】:

我从谷歌读到一个关于设计一个支持快速插入、擦除和擦除随机元素的类的面试问题。我正在考虑 cpp 中的 unordered_set,插入和擦除已经存在。然后对于删除随机元素,我认为 unordered_set 的 begin() 方法指向一个随机元素,我可以获取它的值并将其从集合中删除。这是否总是可以从集合中删除随机值?谢谢!

编辑:如果您能想到其他一些数据结构,请随时发表评论,不必是 unordered_set。

【问题讨论】:

  • 取决于它的随机性。例如,如果您有两个相同的集合,它们的开始迭代器可能指向相同的元素……您只是无法预测它们将是哪些元素。
  • begin() 方法指向实现定义的元素。我认为这不太可能是随机的。
  • hmm... 即使rand 函数通常也是伪随机正确的

标签: c++ data-structures hash hashtable unordered-set


【解决方案1】:

我认为获取begin() 的值不够随机。可能最好自己做一些随机化。一种方法是 从哈希表中随机选择一个桶并取该桶的begin()的值:

#include <unordered_set>
#include <random>

// Assume that T is some arbitrary type for which std::hash<T> is defined
std::unordered_set<T> myset; 

// put some elements into the set

unsigned bcount = myset.bucket_count(); // get the number of buckets
std::mt19937 rng(time(0)); // random number generator (seeded with time(0))

// returns a number in [0, bcount - 1]
uniform_int_distribution<unsigned> d(0, bcount - 1); 

// returns a random bucket index
unsigned rbucket = d(rng); 

// returns the beginning element of the selected bucket
auto it = myset.begin(rbucket); 
myset.erase(it); // removes the selected element

这肯定比取begin() 的值更随机,但仍然不统一,因为首选桶的开始元素。如果你想保证整个容器的均匀分布,你可以简单地在 [0, myset.size()-1] 中取一个随机值r,然后遍历集合到达那个元素:

#include <unordered_set>
#include <random>

// Assume that T is some arbitrary type for which std::hash<T> is defined
std::unordered_set<T> myset;

// put some elements into the set

std::mt19937 rng(time(0)); // random number generator (seeded with time(0))
uniform_int_distribution<unsigned> d(0, myset.size() - 1); 

// returns a random number from [0, myset.size() - 1]
unsigned r = d(rng); 

// iterates through the container to the r-th element
auto it = myset.begin();
for(; it != myset.end() && r > 0; ++it, r--);
myset.erase(it); // erasing the selected element

这会删除具有(伪)均匀概率的元素,但效率不高,因为它需要遍历容器。我认为你不能比使用std::unordered_set 做得更好。

【讨论】:

    猜你喜欢
    • 2013-09-13
    • 1970-01-01
    • 1970-01-01
    • 2022-11-14
    • 1970-01-01
    • 2015-08-02
    • 2020-09-12
    • 1970-01-01
    相关资源
    最近更新 更多