为什么我的Eratosthenes筛选算法失败了?

时间:2015-04-09 12:53:52

标签: ruby algorithm sieve-of-eratosthenes

是的,我知道Eratosthenes的Sieve是标准库Prime课程,但我试图实施自己的练习。

我按照维基百科的说法逐字逐句地说:

  

通过Eratosthenes'找到小于或等于给定整数n的所有素数。方法:   1.创建从2到n的连续整数列表:(2,3,4,...,n)   2.最初,让p等于2,即第一个素数   3.从p开始,通过以p的增量计数n来枚举其倍数,并在列表中标记它们(这些将是2p,3p,4p,......; p本身不应被标记)。
  4.在列表中找到未标记的第一个大于p的数字。如果没有这样的号码,请停止。否则,让p现在等于这个新数字(这是下一个素数),并从步骤3开始重复   5.当算法终止时,列表中未标记的所有数字都是素数。

def sieve(n)
    # Create a list of consecutive integers from 2 through n.   
    list = [*2..n] # [2, 3, 4, 5, etc]
    p = 2 # Let p equal 2, the first prime number

    # Starting from p, enumerate its multiples by counting to n in in increments of p
    loop do
        p1 = p # We'll use this to count in increments, by adding the initial value of p to p each iteration
        until p >= n 
            p += p1
            list.delete(p) # Mark all multiples of p in the list
        end
        if list.find{|x| x > p}
            p = list.find{|x| x > p} # p now equals the first number greater than p in the list that is not marked (deleted)
        else
            return list
        end
    end
end

但是sieve(20)的输出是[2, 3, 5, 7, 9, 11, 13, 15, 17, 19],显然它只是2乘2。

我不确定为什么。

1 个答案:

答案 0 :(得分:4)

您正在更改p,因此list.find{|x| x > p}中的值不是2。也许您想将此部分代码更改为list.find{|x| x > p1}