エラトステネスのふるい

 

キーワード:配列 ,For...Next ,If...EndIf ,Mod演算子 ,Sqr関数 ,Int関数 ,

      ExitステートメントRangeとCells

 

 素数とは,1と自分自身以外には約数をもたない数のことで,

   2,3,5,7,11,・・・

などが素数である.1は素数ではない.

 Nが素数であるか否かは,NがN以下の整数で割り切れるか否かを2まで繰り返し,割り切れるものがあ

った場合は,素数でないとしてループから抜ける.ループの最後までいっても割り切れる数がなかった

ら,その数は素数である.

 なお,NをN/2以上の数で割っても割り切れることはないので,調べる開始の値はNではなくN/2からで

よいことは直感的にわかる.

 数学的にはルートNからでよいことがわかっている.

 

例題1 素数の判定 

 セルA1に記入されている値が素数か否かを判定し,その結果をセルA2に出力せよ.



    Private Sub CommandButton1_Click()

		

		N = Range("A1").Value

		

		If N >= 2 Then

			

			SqrN = Sqr(N)

			Limit = Int(SqrN)



			For I = Limit To 2 Step -1

				If (N Mod I) = 0 Then

					Exit For

				End If 

			Next I

	

 			If I = 1 Then

				Range("A2").Value = N & "は素数" 

			Else 

				Range("A2").Value = N & "は素数でない" 

			End If 

		

		End If 



	End Sub

	

 例題1では,Nが素数か否かを判定したが,同様の考え方を用いて2〜Nまでの全ての素数を求めるプロ

グラムも組めるはずである.

 

例題2 2〜Nの全ての素数

 セルA1に記入されている値までの全ての素数を求め,セルA2から横に10個ずつ出力せよ.つまり,

A2〜J2,A3〜J3,A4〜J4というふう出力する.



	Private Sub CommandButton2_Click()



    	    Dim sosuu(10000)



	        Num = Range("A1").Value

	        M = 1



	        For N = 2 To Num

        

	            SqrN = Sqr(N)

	            Limit = Int(SqrN)

	

	            For I = Limit To 2 Step -1

            

	                If N Mod I = 0 Then

	                    Exit For

	                End If

        

	            Next I



	            If I = 1 Then

	                sosuu(M) = N

	                M = M + 1

	            End If

    

	        Next N



	        J = 1

	        K = 1

        

	        For I = 1 To M

            

	            Cells(J + 1, K).Value = sosuu(I)

	            K = K + 1

	            

	            If K = 11 Then

	                J = J + 1

	                K = 1

	            End If

	            

	        Next I

	

	End Sub



 

 例題2の方法を用いてNまでの素数を求める場合,2〜Nまでの全ての値において素数であるか否かを

判定するので,非常に非効率的である.Nが小さい値のときは別段問題ないが,Nが大きな値になると処

理にかなりの時間がかかってしまう.

 そこで,より効率よく素数を求める方法を紹介しよう.その方法とは,ギリシア時代から知られてい

エラトステネスのふるいという方法である.名前に聞き覚えはないかもしれないが,その具体的な

方法は誰もが一度は目にしていると思う.

 

エラトステネスのふるい

 Nまでの素数を求めるとする.まず,紙に2からNまでの値を全部書く.次に,2を残して2の倍数をす

べて消しゴムで消す.そこで残りの列の2の次を見ると3である.3は素数である.次に,3を残して,3

の倍数をすべて消す.残った列をみると,3の次は5である.4は2の倍数だから,前に消してある.そし

て,5を残して5の倍数を全部消す.このような手続を繰り返すと,素数だけが残ることになる.

 

 このエラトステネスのふるいを用いてNまでの全ての素数を求めるプログラムを作っていく.

 エラトステネスのふるいのアルゴリズムは以下のようになる.

1.2〜Nの数をすべて「ふるい」に入れる.

2.「ふるい」の中で最小値を素数とする.図1の※.

3.今求めた素数の倍数をすべて「ふるい」からはずす.図1の斜線を引いた数.

4.2〜3をNまで繰り返し「ふるい」に残った(斜線を引かれなかった数)が素数である.

               図1 エラトステネスのふるい

 さて実際にプログラムするにあたって,ふるいとして sosuu(2)〜sosuu(N) という配列を用意し,

2〜Nの数を「ふるい」に入れる操作をその配列要素を1にすることにし,「ふるい」からはずす操作を

その配列要素を0とすることにする.

 

例題3 エラトステネスのふるいを用いて 2 〜 N の全ての素数

 エラトステネスのふるいを用いて,例題2と同様に2〜Nの全ての素数を求めよ.


	

	Private Sub CommandButton1_Click()



    	Dim sosuu(10000)

    

    	Num = Range("A1").Value



    	For I = 2 To Num

    	    sosuu(I) = 1

    	Next I

    

    	SqrNum = Sqr(Num)

    	Limit = Int(SqrNum)

    

    	For I = 2 To Limit

    	    If sosuu(I) = 1 Then

    	        For J = 2 * I To Num

    	            If J Mod I = 0 Then

    	                sosuu(J) = 0

    	            End If

    	        Next J

    	    End If

    	Next I

    

    	M = 1

    	L = 1

    

    	For I = 2 To Num

    	    If sosuu(I) = 1 Then

    	        Cells(M + 1, L).Value = I

    	        L = L + 1

    	        If L = 11 Then

    	            M = M + 1

    	            L = 1

    	        End If

    	    End If

    	Next I



	End Sub



 

 

 正の整数を素数の積に分解することを素因数分解という.たとえば,126 = 2*3*3*7 と素因数分解

できる.

 Nを素因数分解するアルゴリズムは以下の通りである.

1.まず,Nを2で割り切れなくなるまで繰り返し割っていく.その際,割り切れるたびに2を表示する.

2.割る数を3として同じことを繰り返し,以後,4,5,6,・・・と続けていく.

   実際には素数についてだけ調べればよいのだが,素数表がないので手当たり次第に調べていく.しかし,素数

   以外のもので割る場合は,それ以前にその数を素因数分解したときの素数(6なら2と3)ですでに割られている

   ので,割り切れることはない.

3.割る数を A としたとき,ルートN ≧ A(N ≧ A×A)の間が2.を繰り返す条件である.

  Nの値も割られるたびに小さくなっていく.

 

例題4 Nの素因数分解

 セルA1の値を素因数分解し,その結果をセルA2から横に出力せよ.




	Private Sub CommandButton1_Click()

	

	    N = Range("A1").Value

    

	    A = 2

	    J = 1

    

	    For I = 1 To N

        

	        If N < A * A Then

	            Exit For

	        End If

	    

	        If N Mod A = 0 Then

	            Cells(2, J).Value = A

	            N = N / A

	            J = J + 1

	        Else

	            A = A + 1

	        End If

	        

	    Next I

	    

	    Cells(2, J).Value = N

    

	End Sub