代码改变世界

[转]线性筛法求质数(素数)表及其原理

2011-01-31 14:16  Hailoong  阅读(734)  评论(0编辑  收藏  举报

参考链接:
http://leonbule.blogbus.com/logs/5342169.html
http://kmplayer.javaeye.com/blog/606352


原理:
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 #include <iostream>
2  using namespace std;
3
4  const int MAX=100;
5  bool isPrime[MAX+1];
6  int total;//计数
7  int prime[MAX+1];
8
9  //线性筛法寻找素数
10  void makePrime()
11 {
12 memset(isPrime,true,sizeof(isPrime));
13 memset(prime,0,sizeof(prime));
14 for(int i=2;i<=MAX;i++)
15 {
16 if(isPrime[i]) prime[total++]=i;
17 for(int j=0; j<total && i*prime[j]<=MAX; j++)
18 {
19 isPrime[i*prime[j]]=false;
20 //i此时不是素数,只是拓展用
21   if(i%prime[j]==0) break;
22 }
23 }
24 }
25
26  int main()
27 {
28 makePrime();
29 for(int i=0;i<total;i++)
30 {
31 cout<<prime[i]<<" ";
32 if((i+1)%10==0) cout<<endl;
33 }
34 return 0;
35 }