浅谈(C语言)Eratoshenes筛法寻找素数与一般算法

爱拉托塞斯筛法(Eratoshenes筛法)是一种寻找素数的方法,又称平凡除法厄拉托塞斯(Eratoshenes)筛法
其是应用定理“设n是正整数,如果对虽有的素数p≤√n,都有p不能整除n,则n一定是素数.”得到的一个寻找素数的确定性方法。下面给出具体描述:
对任意给定的正整数N,要求出所有不超过N的素数。列出N个整数,从中删除不大于√N的所有素数P1,P2,P3,……,Pk的倍数(除素数P1,P2,P3,……,Pk外)。具体的是依次删除,
            P1的倍数:2·P1,3·P1,4·P1,……,[N/P1]·P1;
            P2的倍数:2·P2,3·P2,4·P2,……,[N/P2]·P1;
            P3的倍数:2·P3,3·P3,4·P3,……,[N/P3]·P1;
                    …………
            Pk的倍数:2·Pk,3·Pk,4·Pk,……,[N/Pk]·P1.
余下的整数(不包括1)就是所有求的不超过N的素数([x]表示小于或等于x的最大整数)。

通过上面的的解释,我们知道爱拉托塞斯筛法是指从2到N删去√N内所有素数的2倍、3呗、4呗、……、[N/P1]倍,剩下的就是N内的素数。而通常情况下我们求解N内的素数的一般方法为,i从2到N循环,依次判断i能否被2到√i间的所有数整除,由此来找出N内的素数。看似爱拉托塞斯筛法简单,其实分析得其算法复杂度与循环次数比基本算法要复杂许多,下面分享本人写的2种算法代码及其速度比较:


1.下面是本人写的爱拉托塞斯筛法寻找素数的算法代码:
#include <stdio.h> #include <stdlib.h>
#include <math.h>
#include <conio.h>
#include <time.h>
void main( )
{
    long max,k ,k1,i,j,m,ad,sd;
    sd=0;
    ad=0;
    long *a;
    long start,end;
    printf("请输入一个数:");
    scanf("%ld",&max);                    //输入一个数
    start = clock();
    k=(long)sqrt((float)max);
    printf("开平方后取整k=%ld",k);
    if(NULL==(a=(long*)malloc(sizeof(long)*max)))
    {
        printf("memmery error!\n");
        exit(1);
    }
    for(i=0;i<max;i++){                    //初始化数组a,记录1~max
        a[i]=i+1;
    }
    long *s;                            //s记录K内的素数
    if(NULL==(s=(long*)malloc(sizeof(long)*k)))
    {
        printf("memmery error!\n");
        exit(1);
    }
    for(i=0;i<k;i++){                    //初始化数组s
        s[i]=0;
    }

    for(m=2;m<=k;m++){                    //求k内的素数
        k1=int(sqrt(double(m)));
        for(i=2;i<=k1;i++){                //while(m%i && i<=k1)
            if(m%i==0)                    //  i++;
                break;                    //
        }
        if(i>k1){
            
            s[sd]=m;
            sd++;                        //sd即为k内素数的个数
        }
    }
    printf("\n%ld内的素数有:\n",k);
    for(i=0;i<sd;i++){                
        if(s[i]!=0)
            printf("%ld\t",s[i]);
    }
    
    for(i=2;i<max;i++){                    //爱拉托塞斯筛选
        for(m=0;m<sd;m++){
            for(j=2;j<=(max/s[m]);j++){
                if(a[i]==(j*s[m]))
                    a[i]=0;
            }
        }
    }
    
    end = clock();
    printf("\n不超过%ld的素数有:\n",max);
    for(i=1;i<max;i++){                
        if(a[i]!=0)
            printf("%ld\t",a[i]);
    }
    printf("用时%ld毫秒\n",end-start);
    getchar();
    getchar();
}
编译运行,输入10000,其结果如下,运行时间为863毫秒:

2.下面是本人写的基本一般寻找素数的算法代码:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <conio.h>
#include <time.h>
void main()
{
    long max,k,i,m;
    long start,end;
    printf("请输入一个数:");
    scanf("%ld",&max);                    //输入一个数
    start = clock();
    printf("\n%ld内的素数有:\n",max);
    for(m=2;m<=max;m++){                    //求k内的素数
        k=int(sqrt(double(m)));
        for(i=2;i<=k;i++){                //while(m%i && i<=k)
            if(m%i==0)                    //  i++;
                break;                    //
        }
        if(i>k){
            
            printf("%ld\t",m);
                    
        }
    }
    end = clock();
    
    printf("用时%ld毫秒\n",end-start);
    getchar();
    getchar();
}
编译运行,输入10000,其结果如下,运行时间为81毫秒:



通过上面的比较,发现爱拉托塞斯筛法寻找素数的速度明显比基本算法慢好几倍。
本人技术有限,代码不保证100%完美,些许部分或有不妥或有改善之处,或是你有更好的算法,欢迎评论交流!

#C/C++##笔经#
全部评论

相关推荐

11-08 13:58
门头沟学院 Java
程序员小白条:竟然是蓝桥杯人才doge,还要花钱申领的offer,这么好的公司哪里去找
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务