您的位置:首页 > 编程语言 > C语言/C++

素数的多种判断方法

2017-09-13 13:39 381 查看
首先,贴上素数的最基本定义:素数又称为质数(prime number),定义为在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数(即只能被1和它自身整除的大于等于2的整数。

1.方法一:

#include<iostream>

using namespace std;

int main(){

    int n;

    cin>>n;

    if(n<2)

        cout<<"非素数"<<endl;   //小于2的数,肯定是非素数

    for(int i=2;i<=n-1;++i)

    {

        if(n%i == 0){

            cout<<"非素数"<<endl;

            return 0;

        }

            

    }

    cout<<"素数"<<endl;

    return 0;

}

解释:这是最基本的,也是效率最低的方法。对于一个自然数n来说,需要判断n-2次,时间复杂度为O(n)。但试想,用比n的一半还大的数来整除n,是不是肯定是无法整除的,所以比n的一半还大的数就不用再判断了,进行算法改进,如法二

2.方法二:

#include<iostream>

using namespace std;

int main(){

    int n;

    cin>>n;

    if(n<2)

        cout<<"非素数"<<endl;   

    for(int i=2;i<n/2+1;++i)    //只需要测试从2~n/2+1(n为奇数时候,测试的最后一个数是比n的一半还大的最接近的整数)

    {

        if(n%i == 0){

            cout<<"非素数"<<endl;

            return 0;

        }

            

    }

    cout<<"素数"<<endl;

    return 0;

}

解释:再进一步改进,如果一个数有因子的话,那么在这个数的平方根以内就应该有,否则就肯定没有因子。比如,36的平方根是6,那么在(i>=2 && i<=6)内,就必定有36的因子,所以36是非素数,再比如,99的平方根约为9.95,那么在(i>=2 && i<=9)内必定会有99的因子,所以99是非素数,再比如79,79的平方根约是8.89,在(i>=2
&& i<=8)内没有能整除79的,所以79是素数,见方法三

3.方法三:

#include<iostream>

#include<cmath>

using namespace std;

int main(){

    int n;

    cin>>n;

    if(n<2)

        cout<<"非素数"<<endl;

    double sqrtm = sqrt(n*1.0);//声明一个浮点变量来保存根,i取值为小于sqrtm的最大整数

    for(int i=2;i<sqrtm;++i)    

    {

        if(n%i == 0){

            cout<<"非素数"<<endl;

            return 0;

        }

            

    }

    cout<<"素数"<<endl;

    return 0;
}

解释:当然,算法还可以进一步优化,我们知道,在有的自然数的偶数中,除了2之外,其他的偶数都是合数,都不是素数,所以,算法的关键部分还可以进行以下的修改:

in(n<2)   非素数

if(n==2)   素数

for(int i=3;i<sqrtm;i+=2)  //i从三开始,每次进行加2,调到下一个奇数进行判断。

      if(n%i == 0)

              非素数

4.方法四(筛选法):

用于计算并筛选一定范围内的素数

(1).C

#include<stdio.h>

#include<stdlib.h>

#include<math.h>

#define MAX 1000

int main(){

    int i,j;

    bool isPrime[MAX];

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

        isPrime[i] = 1;//一开始都假设为素数

    double sqrtm = sqrt(1001);

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

        if(isPrime[i])

            for(j=i;i*j<MAX;++j)

                isPrime[i*j] = 0; //标记出非素数

    //自此,素数全部标记为1,非素数全部标记为0

    printf("素数:");

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

        if(isPrime[i] == 1)

            printf("%d,",i);

}

(2).C++.

#include<iostream>

#include<vector>

#include<fstream>

#include<cmath>

using namespace std;

int main(){

    vector<int> prime(5000,1); //一开始都标记为素数

    double sqrtm = sqrt(5000);

    for(int i=2;i<sqrtm;++i)

        if(prime[i])

            for(int j=i;i*j<5000;++j)

                prime[i*j] = 0;     //非素数标记为0

    ifstream in("d:\\a.txt");   //从文件读取数字以进行判断是否为素数

    for(int a;in>>a && a>1 && a<5000;)

        cout<<a<<" is "<<(prime[a]?"":"not ")<<" a prime.\n";

    return 0;

}





PS:还有不少方法,后续更新........
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息