当前位置: 首页 > 知识库问答 >
问题:

提高红宝石中埃拉托色尼筛的效率?

冷翼
2023-03-14

下面是我对埃拉托色尼筛的实现,以找到达到上限参数的质数。

目前,当我的参数为 2,000,000 时,我的代码将在大约 2 秒内完成。我看到我正在通过将数字设置为零来做一个额外的步骤,然后压缩而不是一步删除这些数字。

我将如何着手实现这一点?你还有其他提高我的代码速度的建议吗?

def sieve(upper)
  i = 0
  list = (2..upper).to_a

  (2..Math.sqrt(upper)).each do |mult|
    init = mult + i
    (init..upper-1).step(mult) do |index|
      list[index] = nil
    end
    i += 1
  end
  list.compact
end

共有1个答案

阎乐池
2023-03-14

你可以跳过mult不是素数的循环。

def sieve(upper)
  i = 0
  list = (2..upper).to_a
  (2..Math.sqrt(upper)).each do |mult|
    if list[i] #proceed only when mult is prime
      init = mult + i
      (init..upper-1).step(mult) do |index|
        list[index] = nil
      end
    end
    i += 1
  end
  list.compact
end

这将我的机器上的运行时间从1.9秒减少到0.7秒。不过,我相信还有很多事情可以做。

 类似资料:
  • 就像这个问题一样,我也在厄拉多塞的筛子上工作。同样来自《c语言编程原理和实践》一书的第4章。我能够正确地实现它,并且它的功能完全符合练习的要求。 现在,我怎样才能在输入的中处理真正的大数字?类型应该允许我输入2^32=4,294,967,296的数字。但是我不能,我运行内存溢出。是的,我已经计算过了:存储2^32量的int,每个32位。所以32/8*2^32=16 GiB的内存。我只有4 GiB…

  • 我正在尝试对厄拉多塞的筛子进行并行实现。我做了一个布尔列表,对于给定的大小,用true填充。无论何时发现一个素数,该素数的所有倍数在布尔列表中都被标记为假。 我试图使这个算法并行的方法是在仍然过滤初始质数的同时启动一个新线程。例如,算法从素数 = 2 开始。在 for 循环中,当素数 * 素数时,我做另一个 for 循环,其中检查素数 (2) 和素数 * 素数 (4) 之间的每个数字。如果布尔列表

  • 我试图找到素数使用厄拉多塞筛位数组,但我使用的是无符号整数数组。我需要能够产生多达2,147,483,647个素数。我的代码工作正常,可以生成大约10,000,000个,但是当我增加数组的大小以容纳更大的数字时,它失败了。有人能指导我如何用c语言(不是c语言)使用位向量吗?谢谢 这是我的代码:

  • 我正在尝试让我的埃拉托斯特尼筛程序仅输出用户请求的前n个素数。Sieve本身工作得很好 - 它正确地输出了前100个素数(如下面的数组所示),但是最后一个循环中的计数器变量无法正常工作,我无法找出原因。例如,如果用户输入“5”表示 n,则只会打印前 3 个定焦值。 有人可以帮我找出我的错误吗?我的目的是让“count”成为一个非常简单的计数器,每次都会增加1,直到它达到n。

  • 我遇到了一个分割的埃拉托斯特尼筛子的实现,它promise比传统版本运行快很多倍。有人可以解释一下分段如何改善运行时间吗?请注意,我想在 [1,b] 中找到素数。 它的原理是:(用于查找10^9之前的素数) > 我们首先生成低于 sqrt(10^9) 的筛分素数,这是偶联倍数所必需的。然后我们开始划掉第一个素数2的倍数,直到我们达到2的倍数 为了筛选下一个段,我们重置了筛选数组,并通过segmen

  • 在一个类作业中,我被要求用Java编写Eratostenes筛选代码,我的代码效率非常低。运行时间不长,但我相当肯定,除了像我一样列出所有内容外,还有其他循环的空间。。 这是我的代码: 基本上,我所做的是将所有不是质数的元素设置为true… 所以我的主要2个问题是1。有没有办法实现一个循环,使代码更短2。如何打印此数组中所有为 true(质数)的元素