對於質數的研究

Tomorrowland_D發表於2024-07-24

試除法判斷質數

試除法的思想

試除法是一種簡單且直觀的方法,用來判斷一個數是否為質數。它的基本思想是:對於待判斷的數 ( 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),適用於尋找較小範圍內的素數集合。

相關文章