第7講 配列の学習

第2話 1次元配列の利用

では、皆さん1陣配列を利用した簡単なマクロを作ってみましょう。
第6講第2話で作った『素数列挙マクロ』作った素数を1次元配列に格納して蓄えて、
奇数で割っていくのではなく蓄えた素数で割り算を実行することによって、計算速度をより速くします。
計算速度を測るために、計算時間を測定できるように『素数列挙マクロ
(前に作ったものがどこにあるかわからなくなった人は、素数列挙マクロをダブルクリックして開いてください。)
シート
b1
コード
Private Sub CommandButton1_Click()

  Dim n As Long, i As Long
  Dim cn As Long

  cn = 0
  n = Cells(6, 1)
  For i = 2 To n
    If f(i) = 1 Then
      Cells(6 + Int(cn / 20), 2 + (cn Mod 20)) = i
      cn = cn + 1
    End If
  Next

  Cells(7 + Int(cn / 20), 2) = "素数個数"
  Cells(7 + Int(cn / 20), 3) = cn

End Sub


Function f(n As Long)

  Dim r As Double

  If n = 2 Then
    f = 1
    Exit Function
  End If

  If n Mod 2 = 0 Then
    f = 0
    Exit Function
  End If

  r = Sqr(n)
  For j = 3 To r Step 2
    If n Mod j = 0 Then
      f = 0
      Exit Function
    End If
  Next
  f = 1

End Function


Private Sub CommandButton2_Click()

  Columns("B:AE").Select
  Selection.ClearContents
  Cells(6, 1).Select
  Selection.ClearContents
  Cells(1, 1).Select

End Sub


計算時間が計測できるように、実行コードPrivate Sub CommandButton1_Clickにピンクの行を加えおきます。
Private Sub CommandButton1_Click()

  Dim n As Long, i As Long
  Dim cn As Long
  Dim h As Double, o As Double

  h = Timer

  cn = 0
  n = Cells(6, 1)
  For i = 2 To n
    If f(i) = 1 Then
      Cells(6 + Int(cn / 20), 2 + (cn Mod 20)) = i
      cn = cn + 1
    End If
  Next

  Cells(7 + Int(cn / 20), 2) = "素数個数"
  Cells(7 + Int(cn / 20), 3) = cn

  o = Timer
  Cells(8 + Int(cn / 20), 2) = "計算時間"
  Cells(8 + Int(cn / 20), 3) = o - h


End Sub

こうしておくと、次の実行画面例を見ればお分かりのように、
b2
これで計算時間が計測できるようになりました。
Timerで現在の時間を取得できます。
h = Timerで計算を始める前の時間を取得し、
o = Timerで計算が終了した時点の時間を取得し、
Cells(8 + Int(cn / 20), 3) = o - hにおいて時間差を表示することによって、
計算時間を計測しているわけです。
素数列挙マクロいったん保存してください。
そして、名前付けて保存を使い『素数列挙マクロ改良版』の名で保存してください。


そして、素数の個数を数えるカウンタ変数cnをグローバル変数に変更し、
素数を格納するグローバル配列Dim s(100000000) As Long
を用意して、Functionプロシージャfのコードも次のように変更してください。
Dim s(100000000) As Long
Dim cn As Long

Private Sub CommandButton1_Click()

  Dim n As Long, i As Long
  Dim h As Double, o As Double

  h = Timer

  cn = 0
  n = Cells(6, 1)
  For i = 2 To n
    If f(i) = 1 Then
      Cells(6 + Int(cn / 20), 2 + (cn Mod 20)) = i
      cn = cn + 1
    End If
  Next

  Cells(7 + Int(cn / 20), 2) = "素数個数"
  Cells(7 + Int(cn / 20), 3) = cn

  o = Timer
  Cells(8 + Int(cn / 20), 2) = "計算時間"
  Cells(8 + Int(cn / 20), 3) = o - h


End Sub


Function f(n As Long)

  Dim r As Double

  If n = 2 Then
    s(cn) = n
    f = 1
    Exit Function
  End If

  If n Mod 2 = 0 Then
    f = 0
    Exit Function
  End If

  r = Sqr(n)
  For j = 0 To cn - 1
    If s(j) > r Then
      s(cn) = n
      f = 1
      Exit Function
    End If

    If n Mod s(j) = 0 Then
      f = 0
      Exit Function
    End If
  Next

End Function
ピンクは新たに加えた場所で、は変更した場所)
素数列挙マクロ改良版』を上書き保存してください。
これで、『素数列挙マクロ』と『素数列挙マクロ改良版』の2つが出来ました。
このように名前を付けて保存を活用して、いろいろなバージョンを作る習慣を付けてください。
素数列挙マクロ改良版』の解説は、次話で行うことにして2つの性能比較をしてみましょう。
いずれもb3のとき、
素数列挙マクロ』は
b4
素数列挙マクロ改良版』は
b5
で明らかに、『素数列挙マクロ改良版』の方が計算速度が速くなっていることがわかります。
探索範囲が10,000,000のときは、2倍より速くなっています。
探索範囲が大きくなればなるほど、速度速度はより大きくなっていきます。
解説は次話で行いましょう。

第1話へ 第3話へ

004


vc++講義へ
vb講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座へ
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座へ

数学研究室に戻る