如何在C ++中为std :: map获取随机键?使用迭代器吗?
我不想要维护额外的数据结构。
std::map
迭代器是双向的,这意味着选择一个随机键将会是 O(n)
。不使用其他数据结构,基本上您唯一的选择是使用 begin()
的随机增量以及 std::advance
。例如:
std::map<K, V> m;
auto it = m.begin();
std::advance(it, rand() % m.size());
K random_key = it->first;
rand()
替换为(例如)std::mt19939
)。std :: map
是一个排序的容器,但不支持按元素编号进行随机访问。鉴于此并了解键集,您可以使用 lower_bound
或 upper_bound
随机选择要进入地图的点以找到附近的元素。这倾向于基于地图中它们与其他元素之间的差距选择元素,这意味着如果元素/间隙本身有效随机,则初始结果可能被认为是有效随机的,但是重复选择随机元素将不会均匀分布。真正的随机结果需要通过逐个遍历列表或你想要避免的二级索引容器来实现。
std::next
:) - eripstd::next
吗?为什么它会比std::advance
更好(或不同)? - mannygloverstd::advance
”这个评论在技术上并不完全正确(但实际上确实是正确的选择)。 - eripstd::advance
(和std::next
)的复杂度通常是线性的,但如果容器具有随机访问,例如std::vector
,则为常数。因此,这是一种非常好的完全通用的方法,可以从容器中获取随机元素而不影响性能。 - jmon12