计算素数的几种方法(c++实现)

#include <iostream>
#include <vector>
#include <cmath>
#include <ctime>

using namespace std;

// O(N)
bool isPrime1(int num) {
    for (int i = 2; i < num; ++i) {
        if (num % i == 0) {
            return false;
        }
    }
    return true;
}

// O(N^0.5)
bool isPrime2(int num) {
    int cnt = sqrt(num);
    for (int i = 2; i <= cnt; ++i) {
        if (num % i == 0) {
            return false;
        }
    }
    return true;
}

//  6x-1    6x   6x+1    6x+2    6x+3    6x+4    6x+5    6x+6
//          6x          2(3x+1) 3(2x+1) 2(3x+2)         6(x+1)
// 由上可知,mod6不为1或者5,必定不为素数。
// 但也不代表,mod6为1或者5,就必定为素数。还需要进一步判断。
// 还是由上可知,素数都在6的倍数的两侧:
// 左侧:5开始,步长为6,右侧:左侧的基础加2
// O(N^0.5)
bool isPrime3(int num) {
    if (num <= 3) {
        return num > 1;
    }
    // 不在6的倍数两侧的一定不是质数
    int mod6 = num % 6;
    if (mod6 != 1 && mod6 != 5) {
        return false;
    }
    int cnt = sqrt(num);
    for (int i = 5; i <= cnt; i += 6) {
        if (num % i == 0 || num % (i + 2) == 0) {
            return false;
        }
    }
    return true;
}

// O(N)
vector<int> getPrime1(int num) {
    vector<int> prime;
    if (num >= 2) prime.emplace_back(2);
    if (num >= 3) prime.emplace_back(3);
    for (int i = 5; i <= num; i += 6) {
        prime.emplace_back(i);
        if (i + 2 <= num) {
            prime.emplace_back(i + 2);
        }
    }
    return prime;
}

// O(N^2)
vector<int> getPrime2(int num) {
    vector<int8_t> isprime(num + 1, 0);
    int k = 2, tt = 0;
    while (tt <= num) {
        for(int i = 1; i <= num; i++) { //将不是素数的数筛出
            if(i % k == 0 && i != k) {
                isprime[i] = 1;
            }
        }
        for(int i = 1; i <= num; i++){ //将筛选后的第一个数当做新的筛子
            if(i > k && isprime[i] == 0) {
                k=i;
                break;
            }
        }
        tt++;
    }

    // 获取小于等于num的质数
    vector<int> prime;
    for (int i = 2; i <= num; ++i) {
        if (isprime[i] == 0) {
            prime.emplace_back(i);
        }
    }
	return prime;
}

void test() {
    srand(time(nullptr));
    int n = 10;
    while (n--) {
        int randomNum = rand() % 0xffff + 2;
        if (isPrime1(randomNum)) {
            printf("isPrime1(%d): %d is prime\n\n", randomNum, randomNum);
        } else {
            printf("isPrime1(%d): %d isn't prime\n\n", randomNum, randomNum);
        }
        if (isPrime2(randomNum)) {
            printf("isPrime2(%d): %d is prime\n\n", randomNum, randomNum);
        } else {
            printf("isPrime2(%d): %d isn't prime\n\n", randomNum, randomNum);
        }
        if (isPrime3(randomNum)) {
            printf("isPrime3(%d): %d is prime\n\n", randomNum, randomNum);
        } else {
            printf("isPrime3(%d): %d isn't prime\n\n", randomNum, randomNum);
        }
        vector<int> prime1 = getPrime1(randomNum);
        printf("getPrime1(%d): ", randomNum);
        for (int p : prime1) {
            cout << p << " ";
        }
        cout << endl << endl;
        vector<int> prime2 = getPrime2(randomNum);
        printf("getPrime2(%d): ", randomNum);
        for (int p : prime2) {
            cout << p << " ";
        }
        cout << endl << endl;
    }
}

int main() {
    test();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值