【问题标题】:Randomly generate n unique numbers随机生成 n 个唯一数
【发布时间】:2013-05-20 04:14:50
【问题描述】:

如果我想生成 0 到 999 之间的 1000 个唯一的数字,我该怎么办?
我的第一次尝试是创建一个数组 {0, 1, 2, ..., 999} 并使用std::random_shuffle 来打乱它们。但是,由于我必须在一个长循环中生成数字,比如说 O(10^7),这种方法会占用运行时间。
有没有更好的方法来解决这个问题?

【问题讨论】:

  • 为什么需要 10^7 才能生成 100 个数字
  • @aaronman 这不是 OP 所说的。他需要在一个大约运行 10^7 次的循环中生成它们。
  • 每次使用一组不同的随机数?这样做的目的是什么,我认为如果没有更多信息我们就无法解决问题,您不会每次都生成一组不同的随机数而不遍历所有 1000 个数字。

标签: c++ random shuffle


【解决方案1】:

如果您保存包含 1000 个数字的数组,并且每次需要在循环中调用 std::random_shuffle,这实际上是您能够以您需要的方式生成 1000 个随机唯一数字的最快方式。不需要每次都重新创建数组。

你的循环是否有 O(10^7) 次迭代并不重要,因为如果你要按照你所说的那样使用这 1000 个整数,那么它已经需要 O(n) 次操作才能遍历在您使用它们时,通过这些数字中的每一个。 std::random_shuffle 时间复杂度也是 O(n) 所以它不会让你更慢。

【讨论】:

  • 这个。生成 1000 个数字是 O(n),而 random_shuffle 也是 O(n),所以根据定义,你不能再低了。
  • 渐近地,是的。但简单地读取值可能比生成它们更快。
  • @Elazar 好吧,从硬盘读取实际上比在内存中随机播放要慢。此外,它需要几 GB 的内存来存储所有 100 亿个数字;)
  • @Arthur 从硬盘读取同步可能会更慢。是的。
【解决方案2】:

您要求实现shuffle(这是您要求的准确描述),这将比标准库中的更好。这是一个很长的镜头。

但我会努力的。我会说:准备一个包含 10^7 个这样排列的文件,然后从中读取。确保以某种方式预取,否则它肯定会更慢。如果您在不同的线程中预取,它实际上可能会更快。但这只是一个疯狂的猜测。

当我想到它时,如果您可以运行多线程,则可以使用简单的生产者-消费者解决方案。一个线程放置排列,另一个线程只是读取它们。

【讨论】:

    【解决方案3】:
    1. 将您的号码容器保存到另一个容器 C2。

    2. 生成元素的索引以在 C1 中选择随机元素。每次生成索引时,将其从容器 C1 中删除。 这样,下次您将获得唯一编号。

    3. 一旦 C1 变空,用 C2 重新填充 C1 并转到步骤 2。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-26
      • 2014-05-15
      • 2011-05-16
      • 2018-12-17
      • 2023-03-16
      • 2020-05-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多