线性筛法求质数(素数)表

线性筛法求质数(素数)表

参考:
http://www.cnblogs.com/coeus/articles/1541722.html

原理:
1. 任何一个合数都可以表示成一个质数和一个数的乘积
2. 假设A是一个合数,且A = x * y,这里x也是一个合数,那么有:
       A = x * y; (假设y质数,x合数)
       x = a * b; (假设a是质数,且a < x)
 ->  A = a * b * y = a * Z (Z = b * y)
即一个合数(x)与一个质数(y)的乘积可以表示成一个更大的合数(Z)与一个更小的质数(a)的乘积
这也是理解代码中 if(i%primes[j] == 0)break;的关键
例如: 如果i = 8; 那么由于i%2 == 0; 因此对于i=8就只需要检查primes[1]即可,因为对于大于primes[1]的质数,像3,有:
        8*3 = 2*4*3 = 12*2
也就是说24(8*3=24)并不需要在8时检查,在12时才检查 

代码:
 1  /*
 2   * Problem:
 3   * given an upper bound like U(integer), print all the primes between 0-U
 4   *
 5   * Points:
 6   * this's a O(n) algorithm, amazing
 7    */
 8  #include < stdio.h >
 9  #include < stdlib.h >
10  #include < string .h >
11  #define  MAX_N 250000
12  int  N, hash[MAX_N];
13  int  pcount, primes[MAX_N];
14 
15  void
16  linear_selection()
17  {
18       int  i, j;
19      primes[pcount ++ =   1 ;
20       for (i = 2 ; i <= N; i ++ ) {
21           if ( ! hash[i])
22              primes[pcount ++ =  i;
23           for (j = 1 ; j < pcount  &&  i * primes[j] <= N; j ++ ) {
24              hash[i * primes[j]]  =   1 ;
25               if (i % primes[j]  ==   0 )
26                   break ;
27          }
28      }
29  }
30 
31  int
32  main( int  argc,  char   ** argv)
33  {
34       int  i;
35       while ( 1 ) {
36          printf( " Enter the upper boundary:  " );
37          scanf( " %d " & N);
38           if ( ! N)
39               break ;
40          memset(hash,  0 sizeof (hash));
41          pcount  =   0 ;
42          linear_selection();
43           for (i = 0 ; i < pcount; i ++ )
44              printf( " %d\n " , primes[i]);
45      }
46  }

你可能感兴趣的:(线性筛法求质数(素数)表)