第7講 Subプロシージャ
第3話 Subプロシージャを利用して重複判定を行う
前話問題解答
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
'1から100までの整数の和
f1(0)
End Sub
Sub f1(ByVal w As Integer)
Dim i As Integer
For i = 1 To 100
w = w + i
Next
TextBox1.Text = w.ToString
f2(w) 'プロシージャの独立性のため同じwが使われていても影響がない。
End Sub
Sub f2(ByVal w As Integer)
Dim i As Integer, w As Integer
w = 0
For i = 2 To 100 Step 2
w = w + i
Next
TextBox2.Text = w.ToString
w = w + w
f3(w) 'プロシージャの独立性のため同じwが使われていても影響がない。
End Sub
Sub f3(ByVal w As Integer)
Dim i As Integer, w As Integer
w = 0
For i = 1 To 100
w = w + i * i
Next
TextBox1.Text = w.ToString
w = w + w
f4(w) 'プロシージャの独立性のため同じwが使われていても影響がない。
End Sub
Sub f4(ByVal w As Integer)
Dim i As Integer, w As Integer
w = 0
For i = 2 To 100 Step 2
w = w + i * i
Next
TextBox4.Text = w.ToString
w = w + w
TextBox5.Text = w.ToString
End Sub
End Class
Form1を少し改良して累積値のみを示すように改良しましょう。
この場合f2、f3、f4におけるwは不要になります。
この場合のコードを考えてください。
模範解答例は。30行下。
累積方式模範解答例
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
'1から100までの整数の和
f1(0)
End Sub
Sub f1(ByVal w As Integer)
Dim i As Integer
For i = 1 To 100
w = w + i
Next
TextBox1.Text = w.ToString
f2(w) 'プロシージャの独立性のため同じwが使われていても影響がない。
End Sub
Sub f2(ByVal w As Integer)
Dim i As Integer
For i = 2 To 100 Step 2
w = w + i
Next
TextBox2.Text = w.ToString
f3(w) 'プロシージャの独立性のため同じwが使われていても影響がない。
End Sub
Sub f3(ByVal w As Integer)
Dim i As Integer
For i = 1 To 100
w = w + i * i
Next
TextBox1.Text = w.ToString
f4(w) 'プロシージャの独立性のため同じwが使われていても影響がない。
End Sub
Sub f4(ByVal w As Integer)
Dim i As Integer
For i = 2 To 100 Step 2
w = w + i * i
Next
TextBox4.Text = w.ToString
TextBox5.Text = w.ToString
End Sub
End Class
では次の課題です。
次ようなForm1を作り、
実行すると3桁以内のランダムな数字の行列
が表示されるようなソフトを作ってください。
コード例は、30行下。
コード例
Public Class Form1
Dim a(4, 4) As Integer 'グローバル配列の宣言
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
f1() 'ランダム行列の作成
End Sub
Sub f1()
'変数の宣言
Dim i As Integer, j As Integer
Dim w As String
For i = 0 To 4
For j = 0 To 4
a(i, j) = Int(100 * Rnd())
Next
Next
For i = 0 To 4
For j = 0 To 4
If a(i, j) < 10 Then w = w + "0" + a(i, j).ToString
+ " "
If a(i, j) >= 10 Then w = w + a(i, j).ToString + " "
Next
w = w & vbNewLine
Next
Label1.Text = w
End Sub
End Class
では次の課題です。
Subプロシージャf2を作り、関数f2において
出来たランダムな行列の中に、同じ数字が入っていないかチェックし、
結果を表示させるプログラムを考えてください。
もちろん、Label2を貼り付けておく必要があります。
コード例は30行下。
Public Class Form1
Dim a(4, 4) As Integer 'グローバル配列の宣言
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
f1() 'ランダム行列の作成
f2() '行列内の数字の重複の検査
End Sub
Sub f1()
'変数の宣言
Dim i As Integer, j As Integer
Dim w As String
For i = 0 To 4
For j = 0 To 4
a(i, j) = Int(100 * Rnd())
Next
Next
For i = 0 To 4
For j = 0 To 4
If a(i, j) < 10 Then w = w + "0" + a(i, j).ToString
+ " "
If a(i, j) >= 10 Then w = w + a(i, j).ToString + " "
Next
w = w & vbNewLine
Next
Label1.Text = w
End Sub
Sub f2()
'変数の宣言
Dim i As Integer, j As Integer
'1次元配列の宣言
Dim b(1000) As Integer
'1次元配列の初期化
For i = 0 To 1000
b(i) = 0
Next
'重複検査
For i = 0 To 4
For j = 0 To 4
If b(a(i, j)) = 0 Then
b(a(i, j)) = 1
Else
Label2.Text = "数字の重複がありました。" '結果報告
Exit Sub
End If
Next
Next
'結果報告
Label2.Text = "数字の重複がありませんでした。"
End Sub
End Class
コード解説
For i = 0 To 1000
b(i) = 0
Next
によって、
i | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 〜 |
b(i) | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
A
となります。すると、
の場合、
For i = 0 To 4
For j = 0 To 4
If b(a(i, j)) = 0 Then
b(a(i, j)) = 1
Else
Label2.Text = "数字の重複がありました。" '結果報告
Exit Sub
End If
Next
Next
の一巡目のループで
i | 〜 | 702 | 703 | 704 | 705 | 706 | 707 | 708 | 〜 |
b(i) | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
B
となります。2つの表A,Bを次のようなイメージでとらえてください。
Aにおいてすべて清掃されます。
各セルから、碁石をすべて取り去っているのがA
b(i)=0は碁石がない状態を表します。
すなわち
'1次元配列の初期化
For i = 0 To 1000
b(i) = 0
Next
です。
そして、
For i = 0 To 4
For j = 0 To 4
If b(a(i, j)) = 0 Then
b(a(i, j)) = 1
Else
Label2.Text = "数字の重複がありました。" '結果報告
Exit Sub
End If
Next
Next
によって各セルに碁石をおいていきます。
b(a(i, j))=1が碁石のある状態を表します。セルがすでに碁石が埋まっていておけなければそれは数字の重複を意味しますから
Label2.Text = "数字の重複がありました。" '結果報告 と結果報告がなされ、f2はExit Subによって強制的に終了となります。
もし、めでたくすべての碁石がおければ
'結果報告
Label2.Text = "数字の重複がありませんでした。"
となるというわけです。
ポイントはbの()内がa(i, j)になっている点です。a(i, j)には0から999の整数が入っていました。
したがって、の例ではb(a(0, 0))=b(705)です。
さて、以上の考え方で数字の重複判定は可能なわけですが、
次のような直接的な考え方でも判定は可能です。
1 | 2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 |
1 | 2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 |
(便宜上比べる側を
20 |
で比べられる側を
30 |
で表していますが、両方とも実際には同じです。
色を分けたのは、同じ方陣でも比べる側と比べられる側と役割が違うことを表すためです。)
例えば
31 |
のセルをピンク側のすべてのセルと比較して同じものがないか調べるのです。
この場合、
31 |
のセルは、2次元上を動きます。
また、比べられる側
12 |
セルも2次元上を動きます。
2次元かつ2次元ですから、
2×2=4で4次元になってしまいます。
2次元でさえ頭がこんがりそうなのに、4次元では頭が爆発しそうです。
ですが、、プロシージャをうまく使えば4次元は2次元に落とせます。
つまり、
For i = 0 To 4
For j = 0 To 4
f3(i , j)
Next
Next
のようにすればよいです。
もちろん、f3が2次元ループになっているので積算されて4次元になるのです。
高次元を低次元に落とすことが出来ることがプロシージャの意義の1つです。
皆さん、コーティングを考えてみてください。
第2話へ 第4話へ
VC++講義第1部へ
vb講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
数学研究室に戻る