2012-04-10 5 views
1

私はJavaでEratosthenesのSieveを作成しようとしていますが、私が書いたコードには欠陥があるようです。 私はできないので、他の誰かが私の間違いを見つけられるのだろうかと思っていました。私が得る出力は単純に[2]です。つまり、私のメインループは機能しません。私はちょうどJavaを始めたので、あなたが詳細な答えを与えることができればそれを感謝します。Eratosthenesの故障のふるい

マイコード:

public static int[] primes(int n) 
{ 
    //Variable assignement 
    double sqrt; 
    List<Integer> primes= new ArrayList<Integer>(); 
    //Adds 2 to primes so i don't need to include the even numbers in my for loop. 
    if(n>1) 
    { 
     primes.add(2); 
    } 
    //For loop that goes through the oneven numbers up to n 
    for(int counter1=3;counter1<=n;counter1+=2) 
    { 
     sqrt=Math.floor(Math.sqrt(0.0+counter1)); 
     //for loop that tests if the first for loops number is prime 
     for(int counter2=0;sqrt<=primes.get(counter2);counter2++) 
     { 
      if(counter1 % primes.get(counter2) != 0 && counter2 ==sqrt) 
      { 
       primes.add(counter1); 
      } 

      if(counter1 % primes.get(counter2)==0) 
      { 
       break; 
      } 
     } 
    } 
    return convertIntegers(primes); 
} 
//Converts the list to an array 
public static int[] convertIntegers(List<Integer> integers) 
{ 
    int[] ret = new int[integers.size()]; 
    for (int i=0; i < ret.length; i++) 
    { 
     ret[i] = integers.get(i).intValue(); 
    } 
    return ret; 
} 
+0

コードを少し再フォーマットし、中括弧に一貫したパターンを適用してください。それ以外の場合は、コードを読んで異なるブロックを参照するのは難しいです。 – Thomas

答えて

2

コードを完全にチェックしていませんでしたが、精度に問題がある可能性があります。 doubleは整数値を正確に表現しない可能性がありますので、sqrtが整数であると思われる場合でもcounter2 ==sqrtが偽になる可能性があります。これを防止するために

、以下を試してみてください。

//this is not necessarily a square root anymore, btw :) 
int sqrt = (int) Math.floor(Math.sqrt((double)counter1)); 
... 
for(...) { 
    ... 
    if(... && counter2 ==sqrt) { 
    ... 
    } 
    ... 
} 

編集:分析利回りて

もう少しAこの:

想定し、N = 5、これ以下の手順は次のようになりあなたのコードで実行:

  1. counter1 = 3
  2. sqrt = 1 //床(SQRT(2))
  3. counter2 = 0
  4. counter1 % primes.get(counter2) != 0 && counter2 ==sqrt3 % 2 = 1ので偽であるが、0 != 1
  5. counter1 % primes.get(counter2)==03 % 2 = 1
  6. counter2 = 1ため偽(次の反復)
  7. primes.get(counter2)スロー例外はprimes.get(1)から少なくとも2つの要素を持つprimesが必要です。

あなたが試してみるのは、代わりにcounter2 <=sqrtです。

+0

あなたの回答をありがとう、私はこの問題を解決したかどうか試してみましたが、それはしませんでした。私は2番目のforループでIndexOutOfBoundsExceptionを取得しましたが、なぜcounter2が1の長さから1を引いた値より大きいかを調べることはできません。 – Frank

+0

@Frankはなぜ例外が発生したかの内訳を確認します。 – Thomas

+0

ありがとうございました。私と患者に感謝しています:) – Frank

3
if(counter1 % primes.get(counter2)==0);{ 
    break;} 
} 

は問題を助けすることはほとんどありません。オープニングブレースの前にセミコロンがあります。ブレークは常に実行されます。

+0

ありがとう、mcfinnigan。私はノブのように感じる。しかし、私の指数が範囲外であるというエラーが表示されます。 – Frank

+0

あなたのコードでは、IndexOutOfBoundsExceptionが発生します: 'for(int counter2 = 0; sqrt <= primes.get(counter2); counter2 ++)' - 素数のリストの長さが値の長さ以上であることを確認する必要があります'counter2'。 – mcfinnigan

関連する問題