A Za, A Za, Fighting...

坚信:勤能补拙

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

参考:
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, 0sizeof(hash));
41         pcount = 0;
42         linear_selection();
43         for(i=0; i<pcount; i++)
44             printf("%d\n", primes[i]);
45     }
46 }

posted on 2010-10-17 18:19 simplyzhao 阅读(330) 评论(0)  编辑 收藏 引用 所属分类: G_其他


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


导航

<2010年10月>
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456

统计

常用链接

留言簿(1)

随笔分类

随笔档案

搜索

最新评论

阅读排行榜

评论排行榜