Unordered_set迭代器随机
Unordered_set iterator random
我读到一个来自Google的面试问题,关于设计一个支持快速插入、删除和删除随机元素的类。我在考虑cpp中的unordered_set,插入和擦除已经在那里了。然后对于删除随机元素,我认为unordered_set的begin()方法指向一个随机元素,我可以获取它的值并将其从集合中删除。这是否总是像从集合中删除一个随机值一样有效?谢谢!
编辑:如果你能想到其他的数据结构,可以随意评论,不必是unordered_set
我不认为取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
做得更好。
相关文章:
- 为什么 vector 的随机访问迭代器给出与指针不同的内存地址?
- 如何为我的容器实现随机访问迭代器?
- 对于C++随机访问迭代器(矢量迭代器),迭代器之间的差异是如何计算的?
- 对于随机访问迭代器(矢量迭代器),迭代器C++样式指针吗?
- 随机访问迭代器:我错过了什么?
- 有没有办法在C++中制作无锁"counter"随机访问迭代器?
- 如何确保函数模板的参数是随机访问迭代器
- C++基于现有随机访问迭代器的反向迭代器
- 如何实现随机访问迭代器的"less than operator"?
- 随机访问迭代器和Deque
- 在链表上实现随机访问迭代器
- 为什么使用迭代器时必须重新设定随机生成器种子?
- 从满足谓词的迭代器中均匀随机的容器中获取迭代器
- C++迭代器"for loop"习惯用法,其步长> 1 并允许非随机访问反向迭代器
- 为什么更多的迭代器不是随机访问?
- 如何在C++中比较两个非随机访问迭代器
- 是C 正向/BIDI/随机迭代器总是输出迭代器
- 创建随机迭代器(置换)
- 重载操作符<对于非随机迭代器
- 跳过随机迭代器的一个条目