对于质数的研究

试除法判断质数

试除法的思想

试除法是一种简单且直观的方法,用来判断一个数是否为质数。它的基本思想是:对于待判断的数 ( n ),从小到大地试除每个小于 ( n ) 的数 ( i ),如果 ( n ) 能被任何 ( i ) 整除且 () 和 (),则 ( n ) 不是质数;否则,( n ) 是质数。

下面是用试除法判断一个数 ( n ) 是否为质数的示例代码:

#include <iostream>
using namespace std;

bool isPrime(int n) {
    if (n <= 1) return false; // 小于等于1的数不是质数
    if (n == 2) return true;  // 2是质数
    
    // 从2开始试除,一直试除到 sqrt(n)
    for (int i = 2; i * i <= n; i++) {
        if (n % i == 0) {
            return false; // 如果能整除,则不是质数
        }
    }
    
    return true; // 如果没有能整除的数,则是质数
}

int main() {
    int n;
    cout << "Enter a number: ";
    cin >> n;
    
    if (isPrime(n)) {
        cout << n << " is a prime number." << endl;
    } else {
        cout << n << " is not a prime number." << endl;
    }
    
    return 0;
}

解释:

  1. 函数 isPrime

    • 首先判断如果 ( n \leq 1 ),则返回 false,因为质数定义是大于1的正整数。
    • 如果 ( n = 2 ),则返回 true,因为2是质数。
    • 接下来,用一个循环从2开始到 ( \sqrt{n} )(因为如果 ( n ) 有大于 ( \sqrt{n} ) 的因子,它的对称因子必然小于 ( \sqrt{n} ))逐个试除。
    • 如果能整除任何一个数 ( i ),则返回 false,表示 ( n ) 不是质数。
    • 如果循环结束都没有找到能整除的数,则返回 true,表示 ( n ) 是质数。
  2. 主函数 main

    • 从用户输入一个数 ( n ),然后调用 isPrime 函数判断它是否为质数,并输出相应的结果。

总结:

试除法是一种简单但有效的方法来判断一个数是否为质数。它的时间复杂度为 ( O(\sqrt{n}) ),效率较高,尤其适合用于判断单个数是否为质数的场景。

2.埃氏筛法求质数

埃氏筛(Sieve of Eratosthenes)是一种用来找出一定范围内所有素数的经典算法。它由古希腊数学家埃拉托斯特尼斯(Eratosthenes)发明,用于解决寻找素数的问题。

算法原理

埃氏筛的基本思想是:

  1. 初始化一个布尔类型的数组,称为标记数组(或筛选数组),用来标记每个整数是否为素数。数组的下标表示整数,数组的值为 true 表示该下标对应的整数是素数,为 false 表示不是素数。
  2. 从小到大依次遍历每个整数 i,若发现 i 是素数,则将 i 的所有倍数标记为非素数(即将对应位置的布尔值设为 false),除了 i 本身。

具体步骤如下:

  • 初始化一个布尔数组 is_prime,将数组中所有元素初始化为 true
  • is_prime[0]is_prime[1] 设为 false,因为 0 和 1 不是素数。
  • 2 开始遍历到 sqrt(n),对于每个素数 i,将 i 的所有倍数(除了 i 本身)设为 false
  • 最终,所有值为 true 的下标即为素数。

算法优化

  • 减少遍历范围: 在埃氏筛中,我们只需要遍历到 sqrt(n) 就可以了,因为如果 in 的因子,那么 n/i 也一定是 n 的因子。
  • 空间优化: 如果要找出的素数范围不是很大,可以优化空间。例如,使用标记数组只标记奇数,可以将空间使用减半。

示例

以找出小于等于 n 的所有素数为例,以下是使用埃氏筛的 C++ 实现示例:

#include <iostream>
#include <vector>

std::vector<int> sieve_of_eratosthenes(int n) {
    std::vector<bool> is_prime(n + 1, true); // 默认所有数都是素数
    std::vector<int> primes;

    is_prime[0] = is_prime[1] = false; // 0和1不是素数

    for (int i = 2; i * i <= n; ++i) {
        if (is_prime[i]) {
            for (int j = i * i; j <= n; j += i) {
                is_prime[j] = false; // 将i的倍数标记为非素数
            }
        }
    }

    for (int i = 2; i <= n; ++i) {
        if (is_prime[i]) {
            primes.push_back(i); // 收集所有素数
        }
    }

    return primes;
}

int main() {
    int n = 30; // 找出小于等于30的所有素数
    std::vector<int> primes = sieve_of_eratosthenes(n);

    std::cout << "Prime numbers less than or equal to " << n << " are:\n";
    for (int prime : primes) {
        std::cout << prime << " ";
    }
    std::cout << std::endl;

    return 0;
}

在这个示例中,sieve_of_eratosthenes 函数返回小于等于 n 的所有素数的列表。程序首先初始化一个标记数组 is_prime,然后根据埃氏筛的算法进行标记,最后收集所有值为 true 的下标作为素数输出。

埃氏筛是一种高效的算法,时间复杂度为 O(n log log n),适用于寻找较小范围内的素数集合。

posted @ 2024-07-24 01:01  Tomorrowland_D  阅读(4)  评论(0编辑  收藏  举报