素数筛选法

素数筛选法一直是数论中的重点,你找到的规律越多你的筛选就越快。

先让我们 看一个算法:

#include<stdio.h>
#include<math.h>
#define MAX_P  500
int nList[MAX_P] = {0};
void Calc()
 
{
    int n,p,t,sq=(int)sqrt(MAX_P*2+1);
    for (n=3;n<=sq;n+=2)
    {
        if (nList[n>>1]) continue;
        for (t=n*n;t<=MAX_P<<1;t+=n<<1) //
筛选循环
            nList[t>>1] = 1;
    }
    printf("%5d", 2);
    for (n=t=1;t<MAX_P;++t)
    {
        if (nList[t]) continue;
        printf("%5d", (t<<1)+1);
        if (++n==10)
        {
            printf("\n");
            n=0;
        }
    }
}
int main(void)
{
    Calc();
    getchar();
    return  0;
}

该算法是一种优化的算法,它不仅时间上优化而且在空间上优化了;为什么可以只要开一半的素组,因为素数只可能是奇数(除开2)那么我们可以好好利用该空间;

我们知道奇数除以2是对其取整数了,例如3/2=1,5/2=2......(2*n+1)/2=n;所以我们只要开一半的数组;

for (n=3;n<=sq;n+=2)
    {
        if (nList[n>>1]) continue;
        for (t=n*n;t<=MAX_P<<1;t+=n<<1) //
筛选循环
            nList[t>>1] = 1;
    }
我们都知道对素数的筛选只要到sqrt()就可以了,这里就不证明了,第一个循环是对所有奇数进行筛选,第二个循环是对素数的倍数进行剔除,为什么每次是2*n了,因为n*n是奇数而素数一定是奇数,如果是t+=n;由于t是奇数n也是奇数那么t+=n就是偶数,而t+=2*n就是奇数并且是n的倍数(因为一倍不可能,已证);

如果是它的倍数就标记。

posted @ 2011-08-02 17:48  wutaoKeen  阅读(2660)  评论(0编辑  收藏  举报