簡體   English   中英

Eratosthenes的篩子實施不檢查某些數字

[英]Sieve of Eratosthenes implementation not checking certain numbers

我正在編寫一個程序,使用良好的'Eratosthenes篩選算法(盡管有一個轉折)來查找素數。 為了將所需的字節數組的大小減半,我不代表任何偶數,並堅持使用奇數(通過整數除以2計算它們在數組中的位置)。

但是我有一個問題。 我的程序似乎並不認為17或113為素數,盡管它們確實是素數。 這是我的代碼:

public class Eratosthes {

    byte[] checklist;
    int range;

    public EratosthesConcurrent(int range) {
        this.range = range/2;
        this.checklist = new byte[this.range];
        this.initAllChecked();
        this.findPrimesSeq();
        this.printPrimes();
    }

    private void initAllChecked(){
        for(int i = 1; i < checklist.length; i++){
            checklist[i] = 1;
        }
    }

    private void crossOut(int i){
        checklist[i/2] = 0;
    }

    private void findPrimesSeq(){
        int curr = 3;
        outer: while(curr < range*2){
            for(int i = curr*curr; i < range*2; i+=2*curr){
                if(i != curr && i%curr == 0){
                    if(i == 113){
                        System.out.println(curr);
                    }
                    crossOut(i);
                }
            }

            secondLoop: for(int i = curr; i < range*2; i++){
                if(checklist[i/2] == 1 && curr != i){
                    curr = i;
                    break secondLoop;
                } else if(i == range*2-1 || i == range*2-2){ //Should be changed, might miss the last prime
                    break outer;
                }
            }
        }
    }

    public void printPrimes(){
        for(int i = 1; i < range; i++){
            if(checklist[i] == 1){
                System.out.println("Prime found: " + ((i*2)+1));
            }
        }
    }
}

將以下內容添加到crossOut方法不會產生任何輸出:

if(i == 17 || i == 113){
    System.out.println("Found one of the numbers");
}

這對我來說很奇怪,因為該程序的打印輸出排除了17和113,因此不會檢查它們的任何倍數。 這給我留下了一個字節數組,其中檢查了所有素數......以及17或113的任何倍數。

如果有人能在我的程序中找到錯誤,我會很高興 - 我自己一直在調試它幾個小時,沒有結果。 提前致謝。

問題似乎是你沒有檢查除以2。

你在某個時刻調用crossOut(16) (特別是4的倍數),它會超過17的相應值。 同樣地, 112導致113被划掉。

更改:

if (i != curr && i % curr == 0) {

至:

if (i % 2 != 0 && i != curr && i % curr == 0) {

這兩個都打印成素數。

另外,我有點擔心這個循環究竟在做什么 - 我沒有太詳細地看輸出,雖然它實際上似乎是所有的素數,但我想你應該循環多次的curr ,第一個是2*curr (不是curr*curr ),是curr (不是2*curr )之間的增量,雖然我不是說你做的是不正確的,因為我需要更多的時間來准確理解你的代碼正在解決這個問題。

for(int i = curr*curr; i < range*2; i+=2*curr){

第一個值= 9然后轉到15

curr = 3 - 3 * 3 = 9

i + = 2 * curr = 9 + 6

偽:

outerNum = sqrt[range]
array[boolean] size of range
array[0 & 1] = false

for i = 2 to outernum
       for j  = i to range
           if j % i != 0
               array[j] = false

for i = array[boolean] length
     print if array[i] = true

多數民眾贊成如果有任何錯誤,請記憶。

暫無
暫無

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

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