Naive Primality测试优化

Naive Primality Testing Optimization

本文关键字:优化 测试 Primality Naive      更新时间:2023-10-16

我有一个算法来测试素性,它使用这里列出的naive实现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路段,但在那之后,我迷路了。否则我如何进一步优化速度?

如果你想坚持naive方法,那么你的下一步是使用你链接到的维基百科页面中列出的下一个属性:

所以所有素数的形式都是30k+i,对于i=1,7,11,13,17,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%的速度。当你在列表中添加更多素数时,你会得到递减的回报。

真的,如果你需要快速素数检查,那么你需要远离天真的方法。而且之前有很多关于栈上溢出的问题。