素数算法--之玩转代码

来源:互联网 发布:如何自学汽车电脑编程 编辑:程序博客网 时间:2024/06/11 10:32

   素数筛法是这样的:
    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 3015个单元被标成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);  此方法以微秒为单位获取时间戳

 

 

原创粉丝点击