算法:Eratosthenes 篩選求質數


說明:
   除了自身之外,無法被其它整數整除的數稱之為質數在自然數中,除了1和此整數自身外,不能夠被其他自然數整除的數,稱之為質數。要求質數很簡單,但如何快速的 求出質數則一直是程式設計人員與數學家努力的課題, 在這邊介紹一個着名的Eratosthenes求質 數方法。
 
解法:
  首先知道這個問題可以使用回圈來求解,將一個指定的數除以所有小於它的數,若可以 整除就不是質數,然而如何減少回圈的檢查次數?如何求出小於N的所有質數?
 
 首先假設要檢查的數是N好了,則事實上只要檢查至N的開根號就可以了,道理很簡單,假設 A*B = N,如果A大於N的開根號,則事實上在小於A之前的檢查就可以先檢查到B這個數可以整 除N。不過在程式中使用開根號會精確度的問題,所以可以使用i*i <= N進行檢查,且執行更快。
 
再來假設有一個篩子存放1~N,例如:
 
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ........ N
 
先用2的去做篩選,從4=22 開始,篩去2的倍數,循環步長為2: 2 3 5 7 9 11 13 15 17 19 21 ........ N
 
用3的去做篩選,從9=3開始,篩去3的倍數,循環步長為3: 2 3 5 7 11 13 17 19 ........ N
 
用5的去做篩選,再用5的去做篩選,再用11的去做篩選........,如此進行到最后留下的 數就都是質數,這就是Eratosthenes篩選方法(Eratosthenes Sieve Method)。
 
*/
public class Eratosthenes {

    /**
     * @param args
     */
    public static void main(String[] args) {
        int N = 100;
        int i = 0, j = 0 , count = 0;
        int prime[] = new int[N + 1];

        //初始化數據
        for (i = 2; i <= N; i++) {
            prime[i] = 1;
        }
        //循環1(N 開方 次)
        for (i = 2; i * i <= N; i++) {
            if (prime[i] == 0) {
                count++;
                continue;
            }
            //循環2(N/i 次)  篩選被i整除的數 
            for (j = i * i; j <= N; j = j + i) {
                prime[j] = 0;
                count++;
            }
        }

        System.out.println("Times of calculation : " + count);
        j=0;
        for (i = 2; i <= N; i++) {
            if (prime[i] == 1) {
                System.out.print("\t");
                System.out.print(i);
                j++;
                if(j % 10 == 0){
                    System.out.println();
                }
            }

        }

    }

}

循環次數 O(N):

N 進入循環的次數 循環次數/N
100 109 1.09
1000 1430 1.43
10000 17055 1.70
100000 193328 1.93
1000000 2122879 2.12
10000000 22852766 2.28

 

 

 

 

 

質數可以去http://www.rapidtables.com/math/algebra/Ln.htm進行校驗。


免責聲明!

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



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