ruby - Ruby 中的 Eratosthenes 筛法

标签 ruby sieve-of-eratosthenes

我不想从网上抓取该算法的 Ruby 版本,而是想根据其描述创建自己的 here .但是我无法弄清楚两件事

def primeSieve(n)
  primes = Array.new

  for i in 0..n-2
   primes[i] = i+2
  end

  index = 0
  while Math.sqrt(primes.last).ceil > primes[index]
    (primes[index] ** 2).step(primes.length - 1, primes[index]) 
      {|x| x % primes[index] == 0 ? primes.delete(x) : ""}
    index += 1
  end

  primes
end
  1. 为什么它没有迭代到数组的末尾?
  2. 根据上面链接中的描述,当数组中最后一个元素的平方根大于当前素数时,循环应该被打破——我的以前做过这个。

我相当确定它与修改数组长度的删除操作有关。例如,当我输入 n=10 时,我的函数当前产生 2,3,5,7,9,10,这显然是不正确的。关于如何改变它以使其按预期工作有什么建议吗?

最佳答案

www.scriptol.org 有一个更快的实现:

def sieve_upto(top)
  sieve = []
  for i in 2 .. top
    sieve[i] = i
  end
  for i in 2 .. Math.sqrt(top)
    next unless sieve[i]
    (i*i).step(top, i) do |j|
      sieve[j] = nil
    end
  end
  sieve.compact
end

我认为它可以稍微改进一下:

def better_sieve_upto(n)
  s = (0..n).to_a
  s[0] = s[1] = nil
  s.each do |p|
    next unless p
    break if p * p > n
    (p*p).step(n, p) { |m| s[m] = nil }
  end
  s.compact
end

...主要是因为数组初始化更快,我认为,但它是微不足道的。 (我向两者添加了 #compact 以消除不需要的 nil)

关于ruby - Ruby 中的 Eratosthenes 筛法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/241691/

相关文章:

ruby-on-rails - 用 :if 指定两个条件

c - 使用位数组的埃拉托斯特尼筛法

ruby - 当我指定环境时,为什么 RSpec 在涉及 Sidekiq 的测试中找不到 Airbrake env key ?

ruby - 如何在二维数组中查找

ruby - 为什么字符串比较比整数比较快?

埃拉托斯特尼筛法的 C 代码

java - 关于埃拉托斯特尼筛法

ruby - 调用堆栈 "around"ruby​​代码

scheme - 方案中的埃拉托色尼筛选在其过滤过程中使用局部状态的突变

c - 查找素数时的实现错误