14 Eratosthenes 篩選求質數

說明:除了自身之外,無法被其它整數整除的數稱之爲質數,要求質數很簡單,但如何快速的求出質數則一直是程式設計人員與數學家努力的課題, 在這邊介紹一個着名的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的倍數篩去:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2

3

5

7

9

11

13

15

17

19

21 ........

N

 

 

 

 

 

 

 

 

再將3的倍數篩去:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2

3

5

7

11

13

 

17

19

........

N

 

 

 

 

 

 

 

 

 

 

 

再來將5的倍數篩去,再來將7的質數篩去,再來將11的倍數篩去........,如此進行到最後留下的 數就都是質數,這就是Eratosthenes篩選方法(Eratosthenes Sieve Method) 。 

檢查的次數還可以再減少,事實上,只要檢查6n+1與6n+5就可以了,也就是直接跳過2與3的倍數,使得程式中的if的檢查動作可以減少。

 

********************程序*****************

#include <stdio.h>
#include <stdlib.h>

#define N 1009

int main(void){
     int i, j;
     int prime[N+1];

      for(i = 2; i <= N; i++)
           prime[i] = 1;

      for(i = 2; i*i <= N; i++){ // 這邊可以改進
            if(prime[i]== 1) {
                  for(j = 2*i;j <= N; j++){
                         if(j % i == 0)
                           prime[j] = 0;
                 }
           }
      }

     for(i = 2; i <= N; i++){
         if(prime[i]== 1) {
             printf("%4d ", i);
         }
     }

    printf("\n");
    return 0;
}

 

*******************END*********************

 ************程序2*********************

#include <stdio.h>
#include <stdlib.h>

#define N 1009
int main()
{
    int i,j,flag=0;
   for(i=2;i<=N;i++){
        flag=0;
        for(j=2;j<i;j++){
            if(i%j==0){
                flag=1;
                break;
            }
         }
       if(0==flag)
           printf("%5d",i);
   }
  return 0;
}

 

**************END2*****************

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章