- ベストアンサー
fortranでエラトステネスのふるいを使い3桁の素数を求めるプログラム
- fortranでエラトステネスのふるいを使って3桁の素数を求めるプログラムを作成しました。
- プログラムは、2から99までの数を調べて素数を配列に入れ、その後100から999までの数で割って割り切れるかどうか判定します。
- しかし、プログラムにはバグがあり、素数配列が正しく作成されません。修正方法を教えてください。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
> 1・2~99までの数を素数かどうか調べて、素数を配列に入れていく > 2・100~999まで素数の配列の中の数で割って、割り切れたらおしまい。割り切れなかったら表示していく 「素数を求める」という問題ならこの方法でも間違いではないですが、「エラトステネスのふるい」を使いたいなら、まったく違います。 時間がかかったのでもったいない、という気持ちもわからなくはないですが、「これを直」すより、最初から作りなおした方が早いです。 以下は「ふるい」ではないので、余談となります。 素数判定がうまくいかないのは、判定方法のロジックミスです。 >IF(K ==0)THEN >exit >ELSE IF(K /=0)THEN >l=l+1 >a(l)=N >ENDIF ですが、K==0(=割り切れた)らループ終了、はいいとして そうでない場合、他の素数では割り切れる可能性があるのに素数と判定してしまっています。 具体例では ・15は素数ではありません ・ √5≒3.8... なので、S=3 ・i=2で 15 ÷ 2 = 7あまり1なので、 K=1 ・K==0でないのでELSE節へ ・K/=0なので、THEN以降を実行→15を「素数」と判定 となります。このように、2で割り切れなければ、全て「素数」と判定されます。 ようは「奇数判定プログラム」になっています。 「DO i=2,S,1 のすべてのiについて割り切れなかった」場合が素数です。プログラムもそういう意味になるように作ります。 例えば、 p=0 DO i=2,S,1 .. IF K==0 THEN p=1 exit ENDIF ENDDO IF P==0 THEN 素数 とかのように、途中で割り切れたらフラグを立てる、等です。 後半も判定については同様。さらに >do l=1,99 >X=a(l) >Y=N/X (前半が正しければ) aには2~99までの素数が入っているはずなので、その個数は99ではありません。 個数を越えたところでは、a(l)は初期値のままですから、N/Xの計算もおかしくなります。そもそも、前半ではmodであまりを求めているのに、なぜここではただの割り算になっているのでしょうか? 素数の数は、前半では変数lに入っていましたが、ここでループカウンタに使ってしまったので、もうわかりません。 do i=1,l X=a(i) にすれば、判明している素数だけが使われます。 さらに余談ですが(ELSE以降をループの外に出すので、今回のプログラムでは以下の分は使わない) > IF(K ==0)THEN .. > ELSE IF(K /=0)THEN K==0でないなら、必ずK /=0 です。 ELSEに来る、ということは、K==0ではありません。よって、IF (K/=0)というのは必ず THENを実行します。 こういう場合は IF(K ==0)THEN .. ELSE で十分です。
その他の回答 (3)
- 40000Km
- ベストアンサー率13% (3/23)
エラトステネスのふるいのアルゴリズム まず1000個の配列を用意します(整数型) すべて1の要素には1それ以外の要素に0をセットしておきます 次に2から配列の内容を調べて行きます 配列のi番目が0のときiの2倍、3倍・・・の要素に1をセットします。iの倍数が1000を超えるまで繰り返します。 iが1000に到達したら完了 配列の要素で0のものが素数
お礼
エラトステネスのふるいのふるいの原理はわかりました。 ありがとうございます。 ただ上の文章をプログラムにするだけの能力がありません・・・・
- Tacosan
- ベストアンサー率23% (3656/15482)
「うまく素数配列ができていないよう」と思うなら, 自分で確かめればいいのでは? その結果を見て考えるものではないのですか?
お礼
それができないから聞いているのです。 わざわざ出来ることを質問するようなことはしません
- LOHA
- ベストアンサー率52% (203/388)
パッと見ですが、 IF(K ==0)THEN exit ELSE IF(K /=0)THEN l=l+1 a(l)=N ENDIF だと「割り切れるのが1個でもあったら」というのが表現できていないので、 割れないか = TRUE DO IF(K == 0) THEN 割れないか = FALSE exit ENDIF END DO IF (割れないか) THEN 配列に入れる END IF のようにしないとダメかと思います。 ほんとパッと見なので間違ってたらスミマセン。
お礼
ありがとうございました
お礼
たしかに!!! 全く変なプログラムになっていますね・・・・ ちなみにエラトステネスのふるいをつくるとどうなるのでしょうか?? 教えてください!!!