素数筛法是这样的:
1.开一个大的bool型数组prime[],大小就是n+1就可以了.先把所有的下标为奇数的标为true,下标为偶数的标为false.
2.然后:
for( i=3; i<=sqrt(n); i+=2 )
{ if(prime[i])
for( j=i+i; j<=n; j+=i ) prime[j]=false;
}
3.最后输出bool数组中的值为true的单元的下标,就是所求的n以内的素数了。
原理很简单,就是当i是质(素)数的时候,i的所有的倍数必然是合数。如果i已经被判断不是质数了,那么再找到i后面的质数来把这个质
数的倍数筛掉。
一个简单的筛素数的过程:n=30。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
第 1 步过后2 4 ... 28 30这15个单元被标成false,其余为true。
第 2 步开始:
i=3; 由于prime[3]=true, 把prime[6], [9], [12], [15], [18], [21], [24], [27], [30]标为false.
i=4; 由于prime[4]=false,不在继续筛法步骤。
i=5; 由于prime[5]=true, 把prime[10],[15],[20],[25],[30]标为false.
i=6>sqrt(30)算法结束。
第 3 步把prime[]值为true的下标输出来:
for(i=2; i<=30; i++)
if(prime[i]) printf("%d ",i);
结果是 2 3 5 7 11 13 17 19 23 29
1 #include <stdio.h>
2 #include <math.h>
3 #include <time.h>
4 #include <sys/time.h>
5 #include <unistd.h>
6 #include <stdbool.h>
7
8 //#define NORMAL_PRIME
9 #define N 20000
10 #define false 0
11
12 int main()
13 {
14 int i,j,k,num=0;
15 //time_t time_start,time_end; //seconds
16 //time(&time_start);
17 //clock_t time_start,time_end; //miliseconds
18 //time_start=clock();
19 struct timeval time_start, time_end; //gettimeofday可以取得微秒时间戳
20 struct timezone tz;
21
22 gettimeofday(&time_start,&tz);
23 printf("the time is %ld /n",time_start.tv_usec);
24
25 #ifdef NORMAL_PRIME
26 int prime[N]={0,0,0};
27 printf("the prime is common method/n");
28 for(j=3;j<N;j=j+2)
29 {
30 for(i=2;i<=sqrt(j);i++)
31 {
32 if(j%i==0)
33 break;
34 }
/*35行,这个地方关系运算很关键,如果把>改成 >=就什么素数都 找不到*/
35 if(i>sqrt(j))
36 prime[j]=j;
37 else
38 prime[j]=false;
39 }
40
41 j=1;
42 printf("the prime is /n");
43 for(i=2; i<N; i++)
44 {
45 if(prime[i])
46 {
47 printf(" %d",prime[i]);
48 j++;
49 }
50 if((j%9)==0)
51 {
52 printf("/n");
53 j=1;
54 }
55 }
56 printf("/n");
/*下面的算法就是传说中的筛选法*/
57 #else
58 bool prime[N];
59 printf("the prime is filtering method/n");
60 for(i=2; i<N; i++) //delete the even
61 if(i%2) prime[i]=true;
62 else prime[i]=false;
63
64 for(i=3; i<=sqrt(N); i++) //delete the i*n n=1,2,3...
65 for(j=i+i; j<N; j+=i)
66 prime[j]=false;
67 j=1;
68 printf("the prime is /n");
69 for(i=2; i<N; i++)
70 {
71 if(prime[i])
72 {
73 printf(" %d",i);
74 j++;
75 }
76 if((j%9)==0)
77 {
78 printf("/n");
79 j=1;
80 }
81 }
82 printf("/n");
83
84 #endif
85 //time(&time_end);
86 //time_end=clock();
87 //printf("the time is %ld /n",time_end);
88
89 gettimeofday(&time_end,&tz);
90 printf("the time is %ld /n",time_end.tv_usec);
91 printf("the time is %ld /n",time_end.tv_usec-time_start.tv_usec);
92
93 return 0;
94 }
顺便说一下,时间的获取方法:
1 time_t tm;
time(&tm) 此方法以秒为单位获取时间戳
2 clock_t tm;
tm = clock(); 此方法以毫秒为单位获取时间戳
3 struct timeval tm;
Struct timezone tz;
Gettimeofday(&tm,&tz); 此方法以微秒为单位获取时间戳