第4講 If文の学習
第12話 並び替えソース例解説
ソース例
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
・
・
・
'並び替え
Dim w1 As String, bn As Integer
For i = 40 To 2 Step -1
min = 500
For j = 1 To i
If DataGridView1(6, j).Value <= min Then
min = DataGridView1(6, j).Value
bn = j
End If
Next
For j = 0 To 12
w1 = DataGridView1(j, bn).Value
DataGridView1(j, bn).Value = DataGridView1(j, i).Value
DataGridView1(j, i).Value = w1
Next
Next
End Sub
End Class
初心者の方には、超難解ですね。
2次元ループだからです。解説しましょう。
ループ文を読む上で大切なことは、
各変数の役割を把握することです。
ここでは、i,j,min,bnが登場します。
jは2個登場しますが、1個目と2個目(上と色を対応させています)では役割が全然違います。
1人2役です。
iは、探索範囲行です。
データは2行目から入っていますが、DataGridViewでは1行目を0行目と数えますので、
出席番号とiが一致しております。
始めは40から始まりますので、40行が、つまり出席番号1番から40番までが、探索範囲です。
次にi--によって一つ減りますから、39行が探索範囲です。
1行探索範囲が減ったのは、1回目の探索で40人中の最低点者(同点者が複数いた場合は、番号最下位者)を明らかにしているので、
その最低点者の順位は一応40位に確定しますので、
探索対象から外すのです。
2回目も最低点者を確定して、探索から外し次は38人が探索範囲になります。
以下同様にして、それぞれの人数の中の最低点者を確定し除外を繰り返すことによって、
すべての順位を確定しようとしているわけです。
min = 500
は、5教科の合計なので最低点が500点ということも理論的にはあり得ますので、今回はmin = 500としています。
もし、全員が全教科満点なら最低点は500点ですよね。
もちろん、実際にはそんなことはあり得ません。
もし、コンピュータで宇宙時間(宇宙の始まりから終わりまでの時間)試行実験を繰り返させたとしても1回も表れないでしょう。
ですが、minはどんなに大きくとっても問題ありません。すぐに、
For j = 1 To i
If DataGridView1(6, j).Value <= min Then
min = DataGridView1(6, j).Value
bn = j
End If
Next
でデータが修正されるからです。むしろ、間違いが起きないように大きな値にしておいた方がよいのです。
jの1個目の
For j = 1 To i
If DataGridView1(6, j).Value <= min Then
min = DataGridView1(6, j).Value
bn = j
End If
Next
のjの役回りは何でしょうか。このjは探索行を表しています。
探索範囲は1行目からi行目までであったことに注意して下さい。
iは前の説明の通り、40→39→38→・・・と1つずつ小さくなっていきます。
したがって、iの1回目ではjは1から40まで動き、
iの2回目では1から39まで動き、
iの3回目では1から38まで動き、
・
・
・
となります。
1回1回探索範囲は1つずつ小さくなっていきますが、その探索行すべてを動くのが1個目のjの役割です。
この1個目のループ文
For j = 1 To i
If DataGridView1(6, j).Value <= min Then
min = DataGridView1(6, j).Value
bn = j
End If
Next
の任務は何でしょうか。探索行中の最低点とその人の出席番号を見いだすことです。
DataGridView1(6,j).Value <=minと=が入っていますので、同点者がいた場合出席番号が大きい方が優先されます。
例えば、出席番号26番の人と35番の人が同じ点数(仮に15点とします。)で最低点者であるとします。
するとj=26のときに、If文が実行され、min=15、bn=26となります。
また、j=35のときIf文の条件式の中身は15<=15となり、これは正しいのでここでもIf文は実行され、
min=15,bn=35となりますから、同点の場合出席番号が遅い方が対象者に選ばれます。
もちろん、出席番号が若い方を対象者に選びたいなら DataGridView1(6,j).Value <=minを
DataGridView1(6,j).Value <minに変更すればよいのです。これならば、
j=35のときは、if文の条件式の中身は15>15となりこれは正しくないのでif文は実行されませんので、
jn=26は更新されず、出席番号26番が最低点者の代表に選ばれることになります。
jの2個目のループ文
For j = 0 To 12
w1 = DataGridView1(j, bn).Value
DataGridView1(j, bn).Value = DataGridView1(j, i).Value
DataGridView1(j, i).Value = w1
Next
においてはjはどんな役を演じているのでしょうか。2回目の役は、列数です。
A列からL列は列数でいうと、0列から12列です。
したがって、j = 0 To 12によって対象にされる列は、A列からL列です。
ではそれを対象にして、
For j = 0 To 12
w1 = DataGridView1(j, bn).Value
DataGridView1(j, bn).Value = DataGridView1(j, i).Value
DataGridView1(j, i).Value = w1
Next
では何をしているのでしょうか。
w1を何のために用意したか思い出せば答えは明らかです。
もし、iの1回目なら35番(先に想定した例の場合)と40番の人の行を
1列ずつ交換することによって、行丸ごと交換してしまうことが任務です。
すなわち、
j=0では、 の交換
j=1では、 の交換
j=2では、 の交換
j=3では、 の交換
j=4では、 の交換
・
・
・
j=12では、の交換
以上を通して、
の行丸ごとの交換を実現することが任務です。
トレースしてみましょう。
j=0のとき、
w1 = DataGridView1(j, bn).Valueでw1 = DataGridView1(0, 35).Valueとなり、w1には35が入ります。
・
・
iの1回目においては、w1 = DataGridView1(j, 35).Value
の35と出席番号35は一致していましたね。35はもちろん図の赤い囲いの35です。
すなわち出席番号です。
DataGridView1(j, bn).Value = DataGridView1(j, i).ValueでDataGridView1(0, 35).Value = DataGridView1(0, 40).Value
となり、40行目(これは40番でなくなっていると考える方が妥当です。j=35になる前にすでに交換されている可能性が高いからです。)
の出席番号が35行目に入ります。そして、
DataGridView1(j, i).Value = w1によってDataGridView1(0, 40).Value = w1となり、
40行目の出席番号が35となるわけです。
結局、3行によって0列目(すなわちA列)の35行目と40行目が交換されています。
以下、j=1なら1列目(すなわちB列)の35行目と40行目が、
j=2なら2列目(すなわちC列)の35行目と40行目が、
j=1なら3列目(すなわちD列)の35行目と40行目が、
・
・
・
と1列ごとにセルを交換して、
j=0では、 の交換
j=1では、 の交換
j=2では、 の交換
j=3では、 の交換
j=4では、 の交換
・
・
・
j=12では、の交換
のすべてが実行されて行ごとの交換が完了するわけです。
では課題を出してこの話を終了しましょう。
順位欄にデータを入れてください。
単に1,2,3,・・・,40と入れたのでは、同点者がいた場合正しい順位ではありません。
If文を使って、正しい順位になるように工夫してください。
そして、順位付けが終わったならもう一度出席番号順に並び替えして、この講の課題(成績一覧表の作成)は成就したことになります。
VC++講義第1部へ
vb講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
数学研究室に戻る