我搜索了我能想到的每个网站,并且无法确定ruby 1.8用于在mathn下的Prime类中创建素数列表的基本算法。以下是succ方法的可运行版本,称为100次(为了找到第100个素数)。有谁知道这是如何工作的?
number_of_primes = 100
seed = 1
primes = Array.new
counts = Array.new
while primes.size < number_of_primes
i = -1
size = primes.size
while i < size
if i == -1
seed += 1
i += 1
else
while seed > counts[i]
counts[i] += primes[i]
end
if seed != counts[i]
i += 1
else
i = -1
end
end
end
primes.push seed
counts.push (seed + seed)
end
puts seed
实际代码当然是:http://ruby-doc.org/stdlib-1.8.7/libdoc/mathn/rdoc/Prime.html
它看起来不像筛选算法,因为没有预先筛选的预定义列表,它不是试验分割算法,因为没有除法或模数运算。我完全被难过了。
答案 0 :(得分:5)
该算法基于Eratosthenes的筛子。
seed
是针对完整性进行测试的整数。 primes
是小于seed
的素数列表,counts
包含大于seed
的相应最小倍数。
将counts
视为“下一个”划掉数字的列表,但每个素数只有一个,不断更新。当找到下一个最大倍数时,如果我们得到seed
,那么它不是素数,因此它会重置外部循环(使用i=-1
)。
只有当我们更新了更多倍数的列表,而不会完全遇到seed
时,我们才能推断出seed
是素数。
这里的代码略有简化并注释:
number_of_primes = 100
seed = 1
primes = []
counts = []
while primes.size < number_of_primes
seed += 1
i = 0
while i < primes.size # For each known prime
while seed > counts[i] # Update counts to hold the next multiple >= seed
counts[i] += primes[i] # by adding the current prime enough times
end
if seed != counts[i]
i += 1 # Go update next prime
else
i = 0 # seed is a multiple, so start over...
seed += 1 # with the next integer
end
end
# The current seed is not a multiple of any of the previously found primes, so...
primes.push seed
counts.push (seed + seed)
end
puts seed