我有一个算法来测试素数,它使用了这里列出的天真实现http://en.wikipedia.org/wiki/Primality_test#Naive_methods
static boolean check(int n)
{
if(n == 2 || n == 3)
{
return true;
}
if(n < 2 || n % 2 == 0 || n % 3 == 0)
{
return false;
}
for(int i = 6; i * i <= n; i += 6)
{
if(n % (i - 1) == 0 || n % (i + 1) == 0)
{
return false;
}
}
return true;
}
我一直到6k + 1部分,但在那之后,我迷路了。我还能如何进一步优化速度?
答案 0 :(得分:2)
如果您想坚持使用朴素方法,那么下一步就是使用您链接到的维基百科页面中列出的下一个属性:
因此,对于i = 1,7,11,13,17,所有素数都是30k + i的形式, 19,23,29(即对于i <30使得gcd(i,30)= 1)。
除了你可能选择略微不同/更多的素数而不是2.3.5
你会用一个30步进循环替换6步进循环,(并用手检查所有小于30的质数)
代码可能如下所示:
static boolean check(int n)
{
if(n<30)
{
return n==2 || n==3 || n==5 || n==7 || ...
}
for(int i = 30; i * i <= n; i += 30)
{
if (n % (i + 1))==0 return false;
if (n % (i + 7))==0 return false;
if (n % (i + 11))==0 return false;
if (n % (i + 13))==0 return false;
if (n % (i + 17))==0 return false;
if (n % (i + 19))==0 return false;
if (n % (i + 23))==0 return false;
if (n % (i + 29))==0 return false;
}
return true;
}
但是你会注意到这会扫描8/30(= 27%)个数字,而6个步进循环扫描2/6 (= 33%)所以它扫描的数字减少了约20%,所以你期望最多加速20%。当您向列表中添加更多素数时,您将获得递减收益。
真的,如果你需要快速素数检查,那么你需要摆脱天真的方法。之前有很多关于堆栈溢出问题的问题。