帮助理解eratosthenes筛子的实施

时间:2011-05-22 15:33:04

标签: c# linq sieve-of-eratosthenes

我在这个网站上发现了这种eratosthenes筛的LINQ实现。我理解筛子的基本概念,但有一个细节我没有得到。第一个Enumerable.Range(0,168)的目的是什么?

List<int> erathostheness = Enumerable.Range(0, 168)
.Aggregate(Enumerable.Range(2, 1000000).ToList(), (result, index) =>
{
    result.RemoveAll(i => i > result[index] && i % result[index] == 0);
    return result;
}).ToList();

2 个答案:

答案 0 :(得分:3)

筛选将从列表中删除所有非素数的次数。

result.RemoveAll(i => i > result[index] && i % result[index] == 0);

每次运行筛子时,这行代码都会获取列表中最小的数字(result尚未删除其所有倍数的最小素数),然后删除所有的倍数。这是运行168次,并且在第168次,列表尚未被筛选的最小数字是997,这自然是第168个素数。

这只需要运行168次,因为所有数字都可以表示为素数列表的乘积,并且没有小于1000000的数字是第169个素数(1,009)的倍数不是低于1009的素数的倍数。通过筛选出尚未被移除的1009而去除的最低数量是1009 * 1013 = 1,022,117,或者第169个素数乘以第170个素数,这显然大于100000,因此不需要检查这组数字。

因此,当你到达那一点时,1009的所有倍数都已从列表中删除,所以继续没有意义,因为你已经从列表中删除了所有非素数。 :d

答案 1 :(得分:2)

有168个素数低于1000.

如果x小于1,000,000x不是素数,则x可以计入素数p1, p2, ..., pn。这些因素中至少有一个必须小于1000,否则产品将超过1,000,000。这意味着至少有一个因素必须是前168个素数中的一个。