这个问题与这个有关,更确切地说是与这个答案有关。
我有一个C++/TR1无序集合
更详细地说,这里的“随机性”概念是,两个调用应该产生略微不同的子集——差异越大越好,但这并不是太关键。例如,我会满意于
我目前的进展:
1.平凡方法:选择随机索引
2.桶法(我从上面的链接中“新”获得的):像上面一样选择
我的问题如下:
我有一个C++/TR1无序集合
U
,其中包含无符号整数(大约100-50000个,值范围大约为0到10^6)。给定一个基数N
,我想尽快迭代U
中的N
个随机但唯一的成员。对于N
,没有典型的值,但它应该对小的N
快速工作。更详细地说,这里的“随机性”概念是,两个调用应该产生略微不同的子集——差异越大越好,但这并不是太关键。例如,我会满意于
N
个连续的(或环绕的连续)U
成员块,只要该块的起始索引是随机的。非连续的代价相同,但主要问题是速度。U
在调用之间轻微变化,但不断变化(大约0-10个元素在调用之间插入/擦除)。我目前的进展:
1.平凡方法:选择随机索引
i
,使得(i+N-1) < |U|
,获取到一个迭代器it
,使用it++
将其向前推进i
次,然后开始子集的实际循环。优点:容易。缺点:浪费了许多++。2.桶法(我从上面的链接中“新”获得的):像上面一样选择
i
,找到i
所在的bucket b
,获取到一个局部迭代器lit
,通过lit++
推进lit
,直到我们命中U
的第i个元素,然后继续增加lit
,直到N
次。如果我们遇到了bucket的末尾,我们从下一个bucket的开头继续使用lit
。如果我想让它更随机,我可以完全随机地选择i
并围绕buckets进行包装。我的问题如下:
- 关于上述的第二点,如果我已经找到了第i个元素,是否真的无法以某种方式获得一个指向
U
中迭代器呢?这将减少我对于bucket边界控制等的需求。对于我这样的初学者来说,标准的前向迭代器似乎应该知道如何在遍历到U
中的第i个元素时继续遍历整个U
,但是当我自己找到第i个元素时,除了通过上述的方法2之外,不应该有其他的遍历U
的方式。 - 还能做什么呢?您是否知道更聪明/更随机的方法?如果可能的话,我不想涉及到手动控制bucket大小、哈希函数等,因为我觉得这些内容有点超出我的理解范围。