【问题标题】:Help understanding eratosthenes sieve implementation帮助了解埃拉托色尼筛的实施
【发布时间】:2011-05-22 15:33:04
【问题描述】:

我在这个网站上找到了 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();

【问题讨论】:

  • 不是埃拉托色尼筛法,它只会使用加法从数组中剔除合数; 它是一个试除素筛,因为它通过试除和测试非零余数来消除一个范围内的合数。它是一种优化版本,因为它只除以找到的素数。这不是一个精确的优化,因为它至少需要估计到范围平方根的素数数量(因为 168 是范围 1000000 到 1000 的素数数量)。更好的版本是here

标签: c# linq sieve-of-eratosthenes


【解决方案1】:

这是运行筛子以从列表中消除所有非素数的次数。

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,因此不会t 需要检查这组数字。

因此,当您到达该点时,所有 1009 的倍数都已从列表中删除,因此没有必要继续,因为您已经从列表中删除了所有非素数。 :D

【讨论】:

  • 我们如何推广这段代码来找出所有小于 n 的素数?在这种情况下,168 的值是多少?
  • @Raj 将 1000000 替换为 n,并将 168 替换为 the prime counting functionsqrt(n) 评估。 TLDR:对于x&gt;=171.25506 * x/(log(x)) 将大于素数计数函数,所以你可以使用它(当然是x = sqrt(n))。
【解决方案2】:

小于 1000 的素数有 168 个。

如果x 小于1,000,000,并且x 不是质数,那么x 可以分解为质数p1, p2, ..., pn。这些因素中的至少一个必须小于1000,否则产品将大于1,000,000。这意味着至少有一个因子必须是前 168 个素数之一。

【讨论】:

  • 谢谢你,A+。您是否碰巧知道这是为什么或有来源?
  • @Dan,我更新了我的答案。如果还是不清楚,能否指出我需要详述的部分?
猜你喜欢
  • 2010-12-08
  • 2023-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多