C ++ tr1 unordered_set随机唯一子集的最快方法

时间:2010-12-15 21:28:40

标签: c++ algorithm random subset unordered-set

这个问题与此有关 this one,更准确地说是this回答它。

这里有:我有一个无符号整数的C ++ / TR1 unordered_set U(粗基数100-50000,粗略值范围0到10 ^ 6)。 给定基数N,我想尽可能快地迭代N随机但是 U的独特成员。 N没有典型值,但它应该 小N快速工作。

更详细地说,这里的“随机性”的概念是 两个调用应该产生一些不同的子集 - 越不同, 越好,但这不是太关键。我会...对连续感到高兴 (或缠绕连续) N U成员的块,只要块的起始索引是随机的。 以相同的成本不连续更好,但主要关注的是速度。 U更改 温和地,但不断地在呼叫之间(在呼叫之间插入/删除大约0-10个元素)。

我走了多远:

  1. 琐碎的方法:
    选择随机索引i,使(i+N-1) < |U|。 获取itU.begin()的迭代器,使用i将其提前it++次,然后启动 子集上的实际循环。优点:容易。缺点:浪费++'es。

  2. 铲斗进场(这是我从上面的链接得到的“新”):
    如上所述选择i,找到第b个元素所在的存储区i,获取local_iterator litU.begin(b)lit通过lit++推进i,直到我们点击U的第lit个元素,然后继续N递增lit i次。U次。如果我们到达桶的末端, 我们从下一个桶的开头继续i。如果我想成功的话 更随机我可以完全随机选择U并包裹桶。

  3. 我的开放性问题:

    1. 对于上面的第2点,我真的无法以某种方式得到一个 一旦找到i - 元素,迭代器就会进入i?这样可以省去我 铲斗边界控制等对我而言相当 初学者,标准的前向迭代器应该知道如何,这似乎是不可思议的 在U项时继续遍历{{1}},但当我自己找到{{1}}项时, 除了通过上面的第2点之外,不应该遍历{{1}}。
    2. 我还能做什么?你知道更聪明/更随意的事吗?如果可能的话,我不想参与手册 控制铲斗尺寸,散列函数等,因为这有点过头了。

1 个答案:

答案 0 :(得分:8)