如何在c ++中获取std :: map的随机密钥?使用迭代器? 我不希望维护额外的数据结构
答案 0 :(得分:20)
std::map
迭代器是双向的,这意味着选择随机密钥将是O(n)
。在不使用其他数据结构的情况下,基本上您唯一的选择是使用std::advance
来自begin()
的随机增量。例如:
std::map<K, V> m;
auto it = m.begin();
std::advance(it, rand() % m.size());
K random_key = it->first;
(如果您有权访问rand()
,可以使用(例如)std::mt19939
替换<random>
。
答案 1 :(得分:1)
这取决于你的目的是什么随机的。 std::map
是一个已排序的容器,但不支持按元素编号进行随机访问。鉴于这一点以及对该组密钥的了解,您可以使用lower_bound
或upper_bound
随机选择要挖掘到地图的点,以查找附近的元素。这倾向于根据它们与地图中的其他元素之间的差距来保持挑选元素,这意味着如果元素/间隙本身是有效随机的,则初始结果可以被认为是有效随机的,随机元素的重复选择将不会是均匀分布。
例如,假设你的键是大写字母,键'C','O','Q'和'S'都在地图中。如果你从AZ生成一个随机字母,你就更有可能最终得到C,O或S而不是Q,因为只有PQR接近Q并且使用上限或下限你最终会选择其中两个,尽管只有4个元素,但仍有2/26的机会。尽管如此,如果开始选择C,O,Q和S有一些随机性,你可以认为差距和选择是随机的。
你可以通过像这样刺入容器来改进一点,然后做一小段随机数的迭代器增量/减量,但它仍然不是真正随机的。
一个真正随机的结果需要在列表中推进逐个遍历,或者要避免使用二级索引容器。