

エラトステネスのふるい(素数の倍数を除いていって残ったのが素数)で3桁の素数を求めて表示したいです。
私が考えたのは、
1・2~99までの数を素数かどうか調べて、素数を配列に入れていく
2・100~999まで素数の配列の中の数で割って、割り切れたらおしまい。割り切れなかったら表示していく
ということです。
しかし下のプログラムではうまく素数配列ができていないようなのです。
ここまでかなり時間がかかったのでこのプログラムに手をいれて
これ以外におかしくなるところもどこを直せばいいのか教えてくださるとうれしいです。
C
C q223.f
C
PROGRAM q223
C
IMPLICIT NONE
C
INTEGER N,i,K,s,l
REAL a(99),b(99),c(99),X,Y
C
real M
C
a(1)=2
a(2)=3
l=2
C
DO N=2,99,1
M=N**(0.5)
S=M
DO i=2,S,1
K=MOD(N,i)
IF(K ==0)THEN
exit
ELSE IF(K /=0)THEN
l=l+1
a(l)=N
ENDIF
ENDDO
ENDDO
C
do N=100,999
do l=1,99
X=a(l)
Y=N/X
if(Y==0)then
exit
else if(Y/=0)then
write(*,*)N
end if
end do
end do
c
end
よろしくおねがいします
No.3ベストアンサー
- 回答日時:
> 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
で十分です。
たしかに!!!
全く変なプログラムになっていますね・・・・
ちなみにエラトステネスのふるいをつくるとどうなるのでしょうか??
教えてください!!!
No.4
- 回答日時:
エラトステネスのふるいのアルゴリズム
まず1000個の配列を用意します(整数型)
すべて1の要素には1それ以外の要素に0をセットしておきます
次に2から配列の内容を調べて行きます
配列のi番目が0のときiの2倍、3倍・・・の要素に1をセットします。iの倍数が1000を超えるまで繰り返します。
iが1000に到達したら完了
配列の要素で0のものが素数
エラトステネスのふるいのふるいの原理はわかりました。
ありがとうございます。
ただ上の文章をプログラムにするだけの能力がありません・・・・
No.1
- 回答日時:
パッと見ですが、
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
のようにしないとダメかと思います。
ほんとパッと見なので間違ってたらスミマセン。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
配列数式の解除
-
2つ以上の変数を比較して最大数...
-
2次元動的配列の第一引数のみを...
-
ListViewで、非表示列って作れ...
-
【VBA】配列とWorksheetFunctio...
-
MATLABにて場合分け関数を定義...
-
Excel-VBAの配列「Public Const...
-
エクセルマクロで配列の値から...
-
VB6 配列を初期化したい
-
エクセルで最小値から0を除く方法
-
特定のセル範囲で4文字以上入力...
-
配列変数の添字が範囲外ですと...
-
VBAについての質問です。 こち...
-
【EXCEL自作関数】頭が揃ってな...
-
VBA Match関数の限界
-
VB.NET2015 サブルーチンの使い方
-
VBA 1次元配列を2次元に追加する
-
PL/SQLのFUNCTIONにおける引数...
-
特定のPCだけ動作しないVBAマク...
-
エクセルで特定の列が0表示の場...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
配列数式の解除
-
2つ以上の変数を比較して最大数...
-
特定のセル範囲で4文字以上入力...
-
VBA 1次元配列を2次元に追加する
-
subの配列引数をoptionalで使う...
-
配列変数の添字が範囲外ですと...
-
2次元動的配列の第一引数のみを...
-
ListViewで、非表示列って作れ...
-
MATLABにて場合分け関数を定義...
-
VB6 配列を初期化したい
-
AES暗号にて、AES_set_encrypt_...
-
配列を任意の数値で埋める方法
-
RPG E仕様書について
-
VBのFunctionで、配列を引数...
-
ビンゴ
-
エクセルで最小値から0を除く方法
-
順列の作成
-
VBA Match関数の限界
-
VLOOKUP関数で、一番下...
-
for each の現在の配列ポインタ...
おすすめ情報