第7講 Subプロシージャ
第4話 Subプロシージャを利用した4次元ループ
全問題解答例
Public Class Form1
Dim a(4, 4) As Integer, h As Integer 'hはf2()においてループを継続するかどうかの判定に使う。h=1なら継続でh=0なら中断という設定にしてある。
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
f1() 'ランダム行列の作成
h = 1
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(1000 * Rnd())
Next
Next
'ランダム行列の表示
For i = 0 To 4
For j = 0 To 4
If a(i, j) < 10 Then w = w + "00" + a(i, j).ToString
+ " "
If a(i, j) >= 10 And a(i, j) < 100 Then w = w + "0"
+ a(i, j).ToString + " "
If a(i, j) >= 100 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
'重複検査 比べる側
For i = 0 To 4
For j = 0 To 4
f3(i, j)
If h = 0 Then Exit Sub
Next
Next
Label2.Text = "数字の重複がありませんでした。"
End Sub
Sub f3(ByVal p As Integer, ByVal q As Integer)
'変数の宣言
Dim i As Integer, j As Integer
'重複検査 比べられる側
For i = 0 To 4
For j = 0 To 4
If p <> i Or q <> j Then 'セルが自分自身と比較しないために必要 セルは常に他のセルと比較しなければならない。
If a(p, q) = a(i, j) Then
Label2.Text = "数字の重複がありました。"
h = 0
Exit Sub
End If
End If
Next
Next
End Sub
End Class
実行例
解説
グローバル変数hは、f2()においてループを継続するかしないかの判定に使われています。
今回のプログラミングではh=0なら不継続、h=1なら継続としています。
逆の設定でもかまいません。
プログラマーがこの辺は自由に設定することが出来ます。
尚、次に学習する戻り値を持つFunctionプロシージャにすればグローバル変数にする必要はありません。
不継続条件0または継続条件1をFunctionプロシージャが返してやればよいからです。
その場合、
'重複検査
For i = 0 To 4
For j = 0 To 4
f3(i, j)
If h = 0 Then Exit Sub
Next
Next
は
'重複検査
For i = 0 To 4
For j = 0 To 4
If f3(i, j) = 0 Then Exit Sub
Next
Next
となります。
今回の注目点は、f3(i, j)の引数です。呼び出す側ではiとjになっていますが、
対応する呼び出される側ではpとqになっているという点です。
実は、引き渡す側と引き渡される側が別の変数名でもかまわないのです。
ただし、pとqで引き渡されたときは、引き渡された側はプロシージャ内でpとqに統一しなければなりません。
今回はそれぞれ1回しか使いませんが、数回使うときには常にpとqでなければならないわけです。
注意しなければならない点は、比べる側と比べられる側に分けていますが、対象は同じ行列
であることを忘れてはなりません。If p <> i Or q <> j Then の条件がなければ例えば705は705と比較してしまいます。
これだといつでも
If a(p, q) = a(i, j) Then
Label2.Text = "数字の重複がありました。"
h = 0
Exit Sub
End If
において重複と判定されてしまいます。705はそれ以外のセルと比較しなければなりませんので、
If p <> i Or q <> j Then の条件が付いているわけです。
さて、難解な4次元ループが比較的わかりやすくなりました。
理由は、比べる側をf2が、比べられる側をf3がそれぞれ担当して分業しているからです。
構造を明確にすることが出来る=これが構造化プログラミングの思想です。
ところで、今回数字が重複している場合
どこが重複しているのか探すのが大変です。そこで改良して、重複している数字がどれかわかるようにしましょう。
解答例は、30行下。
解答例
Public Class Form1
Dim a(4, 4) As Integer, h As Integer 'hはf2()においてループを継続するかどうかの判定に使う。h=1なら継続でh=0なら中断という設定にしてある。
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
f1() 'ランダム行列の作成
h = 1
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(1000 * Rnd())
Next
Next
'ランダム行列の表示
For i = 0 To 4
For j = 0 To 4
If a(i, j) < 10 Then w = w + "00" + a(i, j).ToString
+ " "
If a(i, j) >= 10 And a(i, j) < 100 Then w = w + "0"
+ a(i, j).ToString + " "
If a(i, j) >= 100 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
'重複検査
For i = 0 To 4
For j = 0 To 4
f3(i, j)
If h = 0 Then Exit Sub
Next
Next
Label2.Text = "数字の重複がありませんでした。"
End Sub
Sub f3(ByVal p As Integer, ByVal q As Integer)
'変数の宣言
Dim i As Integer, j As Integer
'重複検査
For i = 0 To 4
For j = 0 To 4
If p <> i Or q <> j Then 'セルが自分自身と比較しないために必要 セルは常に他のセルと比較しなければならない。
If a(p, q) = a(i, j) Then
Label2.Text = "数字の重複がありました。" & vbNewLine + "その数字は"
+ a(p, q).ToString + "です。"
h = 0
Exit Sub
End If
End If
Next
Next
End Sub
End Class
実行例
変更点は、Label2.Text = "数字の重複がありました。" & vbNewLine + "その数字は"
+ a(p, q).ToString + "です。"の1カ所のみです。
さらに、改良してすべての重複している数字を指摘するにはどうしたらよいでしょうか。
本日の課題としてこの話を閉じます。
尚、重複を増やすにはa(i, j) = Int(1000 * Rnd())の1000の部分を小さくすればよいのです。
1000のままだと重複はあっても1カ所程度です。余り小さくしてしまうと、重複しない場合がほとんどないとなってしまいますので、
適当に調整して下さい。
VC++講義第1部へ
vb講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
数学研究室に戻る