判斷素數最有效的算法


目錄

定義

1 常規方法判斷

2 最有效方法判斷

3 測試


定義

約數只有1和本身的整數稱為質數,或稱素數。

 

1 常規方法判斷

根據定義,因為質數除了1和本身之外沒有其他約數,所以判斷n是否為質數,根據定義直接判斷從2到n-1是否存在n的約數即可。

Java代碼如下:

 1 /**
 2      * 判斷是否為素數/質數的常規方法
 3      * 判斷n是否為素數,根據定義直接判斷從2到n-1是否存在n的約數即可
 4      * @param num
 5      * @return
 6      */
 7     public static boolean isPrimeNormal(int num) {
 8         for(int i=2; i<num; i++) {
 9             if(num%i == 0) {
10                 return false;
11             }
12         }
13         
14         return true;
15     }
16  

2 最有效方法判斷


首先看一個關於質數分布的規律:大於等於5的質數一定和6的倍數相鄰,例如5和7,11和13,17和19等等。

證明:令x≥1,將大於等於5的自然數表示如下:
······ 6x-1,6x,6x+1,6x+2,6x+3,6x+4,6x+5,6(x+1),6(x+1)+1 ······

可以看到,不在6的倍數兩側,即6x兩側的數為6x+2,6x+3,6x+4,由於2(3x+1),3(2x+1),2(3x+2),所以它們一定不是素數,再除去6x本身,顯然,素數要出現只可能出現在6x的相鄰兩側。

另外,我們知道,一個數若可以進行因數分解,那么分解時得到的兩個數一定是一個小於等於sqrt(n),一個大於等於sqrt(n),據此,上述代碼中並不需要遍歷到n-1,遍歷到sqrt(n)即可,因為若sqrt(n)左側找不到約數,那么右側也一定找不到約數。

Java代碼如下:

 1 /**
 2      * 判斷是否為素數/質數的最有效方法
 3      * 1.小於5的2和3
 4      * 2.大於等於5的素數一定和6的倍數相鄰,例如5和7,11和13,17和19等等。
 5      * @param num
 6      * @return
 7      */
 8     public static boolean isPrime(int num) {
 9         //兩個較小數另外處理 
10         if(num==2 || num==3) {
11             return true;
12         }
13         
14         //不在6的倍數兩側的一定不是素數
15         if(num%6!=1 && num%6!=5) {
16             return false;
17         }
18         
19         int tmp = (int) Math.sqrt(num);//獲取平方根
20         //在6的倍數兩側的也可能不是素數
21         for(int i=5; i<=tmp; i+=6) {
22             if(num%i==0 || num%(i+2)==0) {
23                 return false;
24             }
25         }
26         
27         return true;
28     }

下面來看下,這兩個方法的性能測試:

 1 public static void main(String[] args) {
 2         int testNum = 1000000;
 3         
 4         //常規方法測試
 5         long start1 = Calendar.getInstance().getTimeInMillis();
 6         for(int i=0; i<testNum; i++) {
 7             isPrimeNormal(i);
 8         }
 9         long end1 = Calendar.getInstance().getTimeInMillis();
10         System.out.println("常規方法,消耗時長(ms):" + (end1 - start1));
11         
12         //最有效方法測試
13         long start2 = Calendar.getInstance().getTimeInMillis();
14         for(int i=0; i<testNum; i++) {
15             isPrime(i);
16         }
17         long end2 = Calendar.getInstance().getTimeInMillis();
18         System.out.println("最有效方法,消耗時長(ms):" + (end2 - start2));
19     }

3 測試

測試結果如下:

 

最后,注明下此算法思想出自:https://blog.csdn.net/huang_miao_xin/article/details/51331710


https://blog.csdn.net/qq_15092079/article/details/80804326

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM