判断素数的四种方法

傻瓜方法

思路:按照素数的定义,除了1和它本身没有其他的因数,就是素数。

#include<stdio.h>
int main()
{
    int i,n;
    while(scanf("%d",&n)!=EOF)
    {
        for(i=2;i<n;i++)
            if(n%i==n)
                break;
        if(i==n)
            printf("Yes\n");
        else
            printf("No\n");
    }
    return 0;
}

缺点:n稍微大点,运行时间就会很长,容易时间超限。

普通解法

思路:比如6,23和32效果是一样的,所以只需对它的前一半进行进行判断就可以了。

#include<stdio.h>
#include<math.h>
int main()
{
    int k,i,n;
    while(scanf("%d",&n)!=EOF)
    {
        k=sqrt(n);
        for(i=2;i<k;i++)
            if(n%i==n)
                break;
        if(i==k)
            printf("Yes\n");
        else
            printf("No\n");
    }
    return 0;
}

缺点:效率虽提高不少,但n稍微大点,运行时间还是会很长。

普通筛选法(埃拉托斯特尼筛法)

思路:所使用的原理是从2开始,将每个素数的各个倍数,标记成合数。一个素数的各个倍数,是一个差为此素数本身的等差数列。(百度)

#include<stdio.h>
int a[1000001]={0};//全局数组,初始化为0,便于后面标记
int main()
{
    long i,j,n;
    for(i=2;i<=1000000;i++)
        if(a[i]==0)
            for(j=i+i;j<=1000000;j+=i)//一个素数的倍数,是一个素数本身为公差的等差数列,所以每次加i
                a[j]=1;//将一个素数的倍数标记为1
    while(scanf("%ld",&n)!=EOF)
    {
        if(a[n]==0&&n!=1)//1不是素数
            printf("Yes\n");
        else
            printf("No\n");
    }
    return 0;
}

理解:比如开始时i=2,那么2的倍数就一定不是素数,所以标记所有2的倍数,同理,3是素数,3的倍数就不是素数,标记为1,当i=4的时候,因为之前被标记过,所以if语句不成立,跳过。
缺点:比如6,在i=2时已经被标记过一遍了,而在i=3时又被标记了一遍,所以还是可以改进。

线性筛法(欧拉筛法)

思路:改进的普通筛法,比如在普通筛法中,6会在2,3的时候被标记两次,而用线性筛法会避免这种问题,因为当i=3的时候,j是从9往后标记的,避免了重复标记。

#include<stdio.h>
int a[1000001];
int main()
{
    long i,j,n;
    for(i=2;i<=1000000;i++)
        if(a[i]==0)
            for(j=i*i;j<=1000000;j+=i)
                a[j]=1;
    while(scanf("%ld",&n)!=EOF)
    {
        if(a[n]==0&&n!=1)
            printf("Yes\n");
        else
            printf("No\n");
    }
    return 0;
}

posted @ 2018-11-22 23:33  Cherish486  阅读(325)  评论(0编辑  收藏  举报