簡體   English   中英

Eratosthenes篩網-實現返回一些非素值?

[英]Sieve of Eratosthenes - Implementation returning some non-prime values?

我用偽代碼在Java中實現了Eratosthenes篩子:

public static void sieveofEratosthenes(int n) {
    boolean numArray[];

    numArray = new boolean[n];
    for(int i = 0; i < n; i++)
        numArray[i] = true;

    int a = 0;

    for(int i = 2; i < Math.sqrt((double)n); i++) {
        if(numArray[i])  {
            for(int j = (int)Math.pow(i, 2); j < n; a++) {
                numArray[j] = false;
                j += (a * i);
            }
        }
    }

    for(int i = 2; i < n; i++) {
        if(numArray[i])
            System.out.println(i);
    }
}

當我15歲時,它給我的輸出是:

2
3
5
7
8
11
12
13
14

為什么其中一些值不正確? 我相信我的錯誤在於我如何定義和使用布爾數組。 謝謝!

        for(int j = (int)Math.pow(i, 2); j < n; a++) {
            numArray[j] = false;
            j += (a * i);
        }

應該讀

        for(int j = (int)Math.pow(i, 2); j < n; j+=i) {
            numArray[j] = false;
        }

SoE的工作方式是獲取每個數字並“刪除”其后所有可被其整除的數字。 所以基本上每個數字x + k * x其中k> 0 這可以通過簡單地添加x到的初始x ^ 2,然后加入迭代x到它來完成。 這里:

for(int j = (int)Math.pow(i, 2); j < n; a++) {
    numArray[j] = false;
    j += (a * i);
}

您不是在添加x而是a * x ,因此隨着a的增加,您將跳過一些數字(因此您將刪除4,6,10,16等,請參見模式嗎?它將2,4,6等添加到初始值),因此您應該堅持:

for(int j = (int)Math.pow(i, 2); j < n; j+=i) {
    numArray[j] = false;
}

問題出在線上

 j += (a * i);

在循環中,此語句逐漸將j乘以a * i 並將其與j相加。

 j = (a * i);

它會工作。 是的,初始化

a=2

因為我們不希望numarray [0]或numarray [1]初始化或使用。 如果有任何疑問,請發表評論。 謝謝

這不會直接解決您的問題,但是由於已經回答了問題,因此我認為重復進行沒有任何意義。 不過,查看您的代碼,我建議使用整數乘法而不是Math.powMath.sqrt來獲得更好的性能,例如:

for(int i = 2; i*i < n; i++) {
    if(numArray[i])  {
        for(int j = i*i; j < n; j += i) {
            numArray[j] = false;
        }
    }
}

不可否認,這些調用只會在外循環的每個迭代中進行一次,因此改進可能不會非常顯着。 但是,調用Math.powMath.sqrt可能比單個整數乘法具有更高的計算強度。 同樣,如果Java執行足夠復雜的優化,則i*i可能只被計算一次,並且在兩個地方都使用,從而節省了更多的計算周期。 在這種情況下,也沒有整數溢出的風險,因為i*i在上面受到整數n

暫無
暫無

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

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