质数,又称“素数”,质数定义为在大于1的自然数中,除了1和它本身以外不再有其他因数。

现在,ljn教大家如何用程序判断质数。

 

1.一般,大家在程序中判断质数都是写一个函数,函数中循环从2到这个数的算数平方根枚举,看看这个数是否能整除枚举的数,如果能,则是质数,反之合数。

C Code:

int pd(int n) {
    int i;
    for(i=2; i<=floor(sqrt(n)); i++)
        if(n%i==0) return 0;
    return 1;
}

C++ Code:

bool pd(int n) {
    for(int i=2; i<=floor(sqrt(n)); i++)
        if(n%i==0) return 0;
    return 1;
}

Pascal Code:

Function pd(n:longint):boolean;
var i:longint;
begin
    for i:=2 to trunc(sqrt(n)) do
        if n mod i=0 then exit(false);
    exit(true);
end;

注:C/C++ Code中,调用了floor函数,Pascal Code中,调用了trunc函数,它们都是把浮点数的小数部分去掉(不是四舍五入)。

    C/C++和Pascal的sqrt函数是求一个数的算术平方根。

    C/C++的floor函数和sqrt函数均在头文件<math.h>中。

 

2.接下来介绍一种Monte-Carlo算法:

  如果n是一个正整数,如果a^(n-1)≡1(mod n),我们说n是基于a的伪素数。如果一个数是伪素数,它几乎肯定是素数。另一方面,如果一个数不是伪素数,它一定不是素数。由于我们可以自由地选取基,所以如果在选取了s个基后发现n都是伪素数,就几乎可以肯定n是素数了。

  它最简单的实现方法是一个循环,时间复杂度为O(s),s越大,准确率越高。

Pascal Code:

Function MR(n:longint):boolean;
var i,a:longint;
begin
    for i:=1 to s do
    begin
        a:=random(n-2)+2;
        if modular_exp(a,n-1,n)<>1 then  exit(false);
    end;
    exit(true);
end;

注:此处调用了modular_exp函数,即计算a^b mod c的值。

  这种思路也可以采用二进制扫描法快速地计算出a^b mod c的值。根据模算术的基本知识,(a*b)mod c=((a mod c)*b)mod c,那么可以把a^b mod c变成一系列较小数的乘积。把b写成二进制(a[t],a[t-1]…,a[1],a[0])。

  这样,有:a^b mod c=a^(a[t]*2^t+a[t-1]*2^(t-1)+…+a[1]*2^1+a[0]*2^0)mod c=((a^(a[0]*2^0)mod c)*(a^(a[1]*2^1)mod c)*…*(a^(a[t]*2^t)mod c))mod c。

  总时间复杂度为O(log3(b))。

 

3.有一些题目会让你输出一个区间的质数,那么大家会想到筛法。

  现在大家常用的筛法是Eraosthenes氏筛法:每次求出一个新的素数,就把n以内的它的所有倍数都筛去。在实现的时候,对于每一个素数p,只需要筛去p×p,p×(p+1),…就可以了,因为p×q(q<p)已经在q的第一个素因子被找到的时候筛去了。

C Code:

#include <stdio.h>

int i,j,a,b;
int f[10000];

void pd(int b) {
    for(i=2; i<=b; i++) if(!f[i])
        for(j=i*i; j<=b; j+=i) f[j]=1;
}

int main() {
    scanf("%d%d",&a,&b);
    pd(b);
    for(i=a; i<=b; i++) if(!f[i])
        printf("%d\n",i);
    return 0;
}
C++ Code:

#include <iostream>
#include <cstdio>

using namespace std;

int a,b;
int f[10000];

void pd(int b) {
    for(int i=2; i<=b; i++) if(!f[i])
        for(int j=i*i; j<=b; j+=i) f[j]=1;
}

int main() {
    cin >> a >> b;
    pd(b);
    for(int i=a; i<=b; i++) if(!f[i])
        cout << i << endl;
    return 0;
}
Pascal Code:

Program ex;
var a,b,i:longint;
    f:array[0..10000] of boolean;

Procedure pd(b:longint);
var i,j:longint;
begin
    for i:=2 to b do if not f[i] then begin
        for j:=i to (b div i) do f[i*j]:=true;
    end;
end;

Begin
    read(a,b);
    pd(b);
    for i:=a to b do if not f[i] then
        writeln(i);
End.

有问题请联系QQ3046036317或加入QQ群555088375。

如果你觉得有用,就点“好文要顶”“关注我”“收藏该文”。