素数判定相关资料

素数(质数)的判定

(1)最基本素数判定方法大家熟悉,只用看看2到n(或n的平方根)之间有没有n的约数:

#include<stdio.h>

void main()

{

    int i,n;

    scanf("%d",&n);

    for(i=2;i<n;i++)

        if(n%i==0)break;

    if(i<n||n==1)puts("No");

    else puts("Yes");

}

此方法适用于判定较少数,数据量大时会超时。

(2)筛选法求素数也重要的求素数方法之一。这种方法主要用于打素数表,如求出n之内的所有素数,其思路是从1开始遇到一个素数就标记一下,并去掉n之内的大于它的所有倍数,直循环到n:

#include<stdio.h>

int n,i,j,a[1000001],p[100000],t=0;

void main()

{

    scanf("%d",&n);

    a[1]=0;

    for(i=2;i<=n;i++)a[i]=1;

    for(i=2;i<=n;i++)

        if(a[i]){

            p[t++]=i;

            for(j=i+i;j<=n;j+=i)a[j]=0;

        }

    for(i=0;i<t;i++)

        printf("%d%c",p[i],i<t-1?' ':'/n');

}

此方法也有局限性,数据量中等时才不会超时,数据量过大时也会超时,而且只能用素数打表,不能对单个数进行判定!

(3)线性筛素数

线性筛法:

理解if(i%prime[ j ]==0)是关键。

原理:
1. 任何一个合数都可以表示成一个质数和一个数的乘积
2. 假设A是一个合数,且A = x * y,这里x也是一个合数,那么有:
       A = x * y; (假设y是质数,x合数)
       x = a * b; (假设a是质数,且a < x  ——>>  a<y)
->  A = a * b * y = a * Z (Z = b * y)
即一个合数(x)与一个质数(y)的乘积可以表示成一个更大的合数(Z)与一个更小的质数(a)的乘积!!!!
这也是理解代码中 if(i%primes[j] == 0)break;的关键
例如: 如果i = 8; 那么由于i%2 == 0; 因此对于i=8就只需要检查primes[1]=2即可,因为对于大于primes[1]的质数,像3,有:
        8*3 = 2*4*3 = 12*2
也就是说24(8*3=24)并不需要在8时检查,在12时才检查

代码:

线性筛法:
#include<iostream> 
using namespace std;
const int n=200000;
long prime[n]={0},num_prime=0;//num_pirme记录素数个数
int main()
{
    int m;
    cin>>m;
    int a[n]={1,1},i,j;
    for(i=2;i<m;i++)
    {
        if(!a[i])
            prime[num_prime++]=i;
        for(j=0;j<num_prime && i*prime[j]<m;j++)
        {
            a[i*prime[j]]=1;//合数标为1,同时,prime[j]是合数i*prime[j]的最小素因子
            if(!(i%prime[j]))//即比一个合数大的质数和该合数的乘积可用一个更大的合数和比其小的质数相乘得到,见例子
                break;
        }
    }
    for(i=0;i<num_prime;i++)//输出
    {
        if(i%10==0)printf("
");
    printf("%3d ",prime[i]);
    }
        printf("
");
    return 0;

}

小知识:

1.高斯猜测,n以内的素数个数大约与n/ln(n)相当,或者说,当n很大时,两者数量级相同。这就是著名的素数定理。

2.十七世纪费马猜测,2的2^n次方+1,n=0,1,2…时是素数,这样的数叫费马素数,可惜当n=5时,2^32+1就不是素数,

至今也没有找到第六个费马素数。

3.18世纪发现的最大素数是2^31-1,19世纪发现的最大素数是2^127-1,20世纪末人类已知的最大素数是2^859433-1,用十进制表示,这是一个258715位的数字。

4.孪生素数猜想:差为2的素数有无穷多对。目前知道的最大的孪生素数是1159142985×2^2304-1和1159142985×2^2304+1。

5.歌德巴赫猜想:大于2的所有偶数均是两个素数的和,大于5的所有奇数均是三个素数之和。其中第二个猜想是第一个的自然推论,因此歌德巴赫猜想又被称为1+1问题。我国数学家陈景润证明了1+2,即所有大于2的偶数都是一个素数和只有两个素数因数的合数的和。国际上称为陈氏定理。

来自 <http://blog.csdn.net/liukehua123/article/details/5482854>

原文地址:https://www.cnblogs.com/liuzhanshan/p/6285677.html