簡體   English   中英

為什么這個素數算法起作用?

[英]Why does this prime number algorithm work?

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main() {
    int anz;
    scanf("%d", &anz);
    time_t start = time(0);
    int *primZ = malloc(anz * sizeof(int));
    primZ[0] = 2;
    int Num = 0;

    for (int i = 1, num = 3; i < anz; num += 2) {
        for (int j = 1; j < i; j++) {
            if (num % primZ[j] == 0) {
                num += 2;
                j = 0;
            }

            //this part
            if (primZ[j] > i / 2)
                break;
        }

        primZ[i] = num;
        i++;
        printf("%d ,",num);
    }

    time_t delta = time(0) - start;
    printf("%d", delta);
    getchar();
    getchar();
    return 0;
}

該代碼運行正常,問題是為什么。 if(primZ[j] > i/2)使程序快2-3倍。 實際上,它本來應該是if(primZ[j] > num/3) ,因為num只能是一個奇數,所以這是很有意義的。 但這是找到的質數的數量。 對我來說完全是無稽之談。 請解釋。

您可以通過檢查素數是否可被已找到的素數除以檢查該素數是否為合成數。 但是這樣做的話,您最多只需要檢查並包括數字的平方根,因為大於該數字的平方的任何數字都會留下小於該數字平方根的數字。

例如33是復合的,但是您只需檢查最多5個數字就可以知道,您不需要檢查它是否可以被11整除,因為它留下了我們已經檢查過的3(33/11 = 3)。

這意味着您可以通過以下方法改進算法

    for (int j = 1; j < i; j++) {
        if( primZ[j]*primZ[j] > num )
             break;

        if (num % primZ[j] == 0) {
            num += 2;
            j = 0;
        }
    }

您可以與i/2處的切割進行比較的原因是質數的分布。 質數計算函數約為i = num/log(num) ,然后得到i/2 > sqrt(num)

原因是實際界限比num/3嚴格得多-您可以使用:

if (primZ[j] > sqrt(num))

原因是,如果比的平方根更高素num除法num ,還必須有一個低素在支持(因為這樣的除法運算的結果必須比平方根較低)。

這意味着只要i/2高於sqrt(num) ,代碼就會起作用。 發生的情況是,小於數字的質數的增長速度快於該數字的平方根,這意味着(完全偶然) i/2是可以安全使用的綁定。

您可以在此處查看i值的行為-他們稱其為pi(x),素數小於x。

這是有道理的,因為如果n有兩個因子,其中一個肯定小於或等於n / 2,則程序會發現在primZ中沒有i因子小於或等於i/2這意味着不存在任何因子。我-除了1當然-。

感知primZ按升序排序,並且j僅增加,當primeZ[j] > i/2 ,表示primZ中不存在小於i / 2的i因子。

PS在for語句num=3的第一部分中說明了開始搜索的要點,而循環語句num += 2確保僅測試奇數

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM