📜  C C++程序查找给定范围之间的素数(1)

📅  最后修改于: 2023-12-03 15:13:44.871000             🧑  作者: Mango

C/C++程序查找给定范围之间的素数

素数是只能被1和自身整除的正整数,本文将介绍如何使用C/C++编程查找给定范围之间的素数。

算法思路

最简单的方法是对于每一个数,从2到其自身减一,判断有没有能够整除它的数。但是这种方法时间效率很低,无法处理大数。常见的优化算法有:

  1. Trial Division (试除法)

试除法是最基本的素数判断方法,它的原理是如果一个数能被整除,那么它只能被小于等于它的数整除。

实现思路是:枚举每个数i,从2到i/2,看i是否有整除数。

  1. Eratosthenes (埃拉托斯特尼筛法)

埃拉托斯特尼筛法的原理是将小于等于一个数的所有素数找出来,然后再筛去这些素数的倍数,剩下的数即为素数。

实现思路是:将小于等于n的所有数先标记为合数,然后从2开始枚举每个素数,将其倍数标记为不是素数。最终,剩下的标记为合数的数就是素数。

  1. Miller-Rabin (米勒 - 罗宾)

Miller-Rabin算法是一种基于概率的算法,它可以快速地判断一个数是否为素数。

实现思路是:对于一个大数n,它是一个合数可能性很高,我们可以选择一些随机的底数a,判断它是否是n的一次方或平方的余数。经过多次测试后,如果每次测试结果都表明n是素数,那么n就极有可能是素数。

代码实现

在本文代码实现中,我们主要采用了试除法和埃拉托斯特尼筛法两种算法。

试除法实现
#include <cstdio>
#include <cstdlib>

// 判断是否为素数,1表示是,0表示否
int is_prime(int n) 
{
    if (n == 1) {
        return 0; // 1不是素数
    }
    for (int i = 2; i <= n / 2; i++) {
        if (n % i == 0) {
            return 0; // 可以被整除,不是素数
        }
    }
    return 1;
}

int main()
{
    int lower, upper;

    printf("请输入范围:\n");
    printf("下界:");
    scanf("%d", &lower);
    printf("上界:");
    scanf("%d", &upper);

    for (int i = lower; i <= upper; i++) {
        if (is_prime(i)) {
            printf("%d ", i);
        }
    }

    printf("\n");

    return 0;
}
埃拉托斯特尼筛法实现
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>

// 判断是否为素数,1表示是,0表示否
int is_prime(int n, int *prime, int len) 
{
    for (int i = 0; i < len && prime[i] <= sqrt(n); i++) {
        if (n % prime[i] == 0) {
            return 0; // 可以被整除,不是素数
        }
    }
    return 1;
}

// 埃拉托斯特尼筛法,返回素数的个数
int eratosthenes(int upper, int *prime) 
{
    int cnt = 0;
    char *flag = new char[upper + 1];
    memset(flag, 0, sizeof(char) * (upper + 1));
    for (int i = 2; i <= upper; i++) {
        if (!flag[i]) {
            prime[cnt++] = i;
            for (int j = i + i; j <= upper; j += i) {
                flag[j] = 1;
            }
        }
    }
    delete[] flag;
    return cnt;
}

int main()
{
    int lower, upper;

    printf("请输入范围:\n");
    printf("下界:");
    scanf("%d", &lower);
    printf("上界:");
    scanf("%d", &upper);

    int *prime = new int[upper + 1]; // 保存素数
    int cnt = eratosthenes(upper, prime);

    for (int i = lower; i <= upper; i++) {
        if (is_prime(i, prime, cnt)) {
            printf("%d ", i);
        }
    }

    printf("\n");

    delete[] prime;

    return 0;
}
总结

本文介绍了基本的素数判断算法和优化算法,并给出了C/C++代码实现。优化算法在处理大数时效率更高,特别是埃拉托斯特尼筛法,时间复杂度为O(nloglogn),空间复杂度为O(n)。科学计算中常常需要大量素数,因此掌握算法对于科研类开发人员具有重要意义。