首先 - 我在这个论坛上查了很多,但我还没找到足够快的东西。 我尝试创建一个函数,返回指定范围内的素数。 例如,我使用Eratosthenes的筛子完成了这个功能(在C#中)。我也尝试了阿特金的筛子,但是Eratosthenes的速度更快(在我的实施中):
public static void SetPrimesSieve(int Range)
{
Primes = new List<uint>();
Primes.Add(2);
int Half = (Range - 1) >> 1;
BitArray Nums = new BitArray(Half, false);
int Sqrt = (int)Math.Sqrt(Range);
for (int i = 3, j; i <= Sqrt; )
{
for (j = ((i * i) >> 1) - 1; j < Half; j += i)
Nums[j] = true;
do
i += 2;
while (i <= Sqrt && Nums[(i >> 1) - 1]);
}
for (int i = 0; i < Half; ++i)
if (!Nums[i])
Primes.Add((uint)(i << 1) + 3);
}
它的运行速度比代码快两倍。我找到的算法...... 应该有更快的方法来找到素数,你能帮助我吗?
答案 0 :(得分:9)
在搜索关于此主题的算法时(对于项目Euler)我不记得找到更快的东西。如果速度确实是关注的问题,您是否考虑过只存储素数而只需要查找它?
编辑:快速谷歌搜索找到this,确认最快的方法只是分页结果并根据需要查找。
再一次编辑 - 您可能会发现更多信息here,基本上是此主题的副本。那里的最高职位是atkin的筛子比现在更快,直到在飞行中生成。
答案 1 :(得分:2)
到目前为止,根据我的经验,最快的算法是使用车轮分解为2,3和5的Erathostenes筛,其中剩余数字中的素数表示为字节数组中的位。在我3岁笔记本电脑的一个核心上的Java中,需要23秒才能计算出高达10亿的素数。
通过车轮分解,Atkin的Sieve大约慢了两倍,而普通的BitSet
大约快了30%。
另见this answer。
答案 2 :(得分:1)
我做了一个算法,可以在I 350M笔记本上找到2-90 000 000范围内的素数,持续0.65秒,用C语言编写....你必须使用按位运算并且有“代码”来重新计算索引你的数组索引你想要的具体位。例如,如果你想要数字2的折叠,具体位将是例如.... 10101000 ...所以如果你从左边读...你得到索引4,6,8 ......就是这样
答案 3 :(得分:0)
几条评论。
对于速度,预计算然后从磁盘加载。它超级快。我很久以前就用Java做过了。
不要存储为数组,存储为奇数的位序列。更有效的记忆方式
如果您的速度问题是您希望此特定计算快速运行(您需要证明为什么您无法预先计算并从磁盘加载它),则需要编写更好的Atkin筛选器。它更快。但只是轻微的。
您尚未指出这些素数的最终用途。我们可能完全错过了一些东西,因为你没有告诉我们申请。告诉我们应用程序的草图,答案将更好地针对您的背景。
为什么你认为存在更快的东西?你没有证明你的预感是正当的。这是一个非常难的问题。 (那就是找到更快的东西)
答案 4 :(得分:0)
使用Sieve of Atkin可以做得更好,但正确地快速实现和非常棘手。维基百科伪代码的简单翻译可能不够好。