第7講 配列の学習
第5話 自然配列・自然配列転置・逆自然配列・逆自然配列転置の解説
コード解説
Dim a(100, 100) As Integer 'グローバル配列
Private Sub CommandButton1_Click()
Dim h As Byte, o As Byte
h = Cells(2, 8)
o = Cells(3, 8)
f0 h, o '自然配列の生成
f1 h, o '自然配列の表示
f2 h, o '自然配列の転置(縦・横交換)の表示
f3 h, o '逆自然配列の表示
f4 h, o '逆自然配列転置の表示
End Sub
'自然配列の生成
Sub f0(h As Byte, o As Byte)
Dim i As Byte, j As Byte
For i = 0 To h - 1
For j = 0 To o - 1
a(i, j) = o * i + j + 1
Next
Next
End Sub
'自然配列の表示
Sub f1(h As Byte, o As Byte)
Dim i As Byte, j As Byte
Cells(6, 1) = "自然配列"
For i = 0 To h - 1
For j = 0 To o - 1
Cells(7 + i, 1 + j) = a(i, j)
Next
Next
End Sub
'自然配列の転置の表示
Sub f2(h As Byte, o As Byte)
Dim i As Byte, j As Byte
Cells(6, 3 + o) = "自然配列の転置"
For i = 0 To o - 1
For j = 0 To h - 1
Cells(7 + i, 3 + j + o) = a(j, i)
Next
Next
End Sub
'逆自然配列の表示
Sub f3(h As Byte, o As Byte)
Dim i As Byte, j As Byte
Cells(6, 5 + h + o) = "逆自然配列"
For i = 0 To h - 1
For j = 0 To o - 1
Cells(7 + i, 5 + j + h + o) = (o - 1) * h + h + 1 - a(i, j)
Next
Next
End Sub
'逆自然配列転置の表示
Sub f4(h As Byte, o As Byte)
Dim i As Byte, j As Byte
Cells(6, 7 + h + 2 * o) = "逆自然配列の転置"
For i = 0 To h - 1
For j = 0 To o - 1
Cells(7 + i, 7 + j + h + 2 * o) = (o - 1) * h + h + 1 - a(i, j)
Next
Next
End Sub
では、自然配列の生成から順に説明していきましょう。
'自然配列の生成
Sub f0(h As Byte, o As Byte)
Dim i As Byte, j As Byte
For i = 0 To h - 1
For j = 0 To o - 1
a(i, j) = o * i + j + 1
Next
Next
End Sub
皆さんが?マークを浮かべた場所は、a(i, j) = o * i + j + 1ではないでしょうか。
oは列数を意味していました。
例えば、行数に4、列数に3と入力したときの実行結果は、
です。
トレースしてみましょう。
T i=0の場合
@ j=0のとき、
a(i, j) = o * i + j + 1 = 3 * 0 + 0 + 1 = 1
で、1行目1列目は1になっています。
A j=1のとき、
a(i, j) = o * i + j + 1 = 3 * 0 + 1 + 1 = 2
で、1行目2列目は2になっています。
B j=2のとき、
a(i, j) = o * i + j + 1 = 3 * 0 + 2 + 1 = 3
で、1行目3列目は3になっています。
U i=1の場合
@ j=0のとき、
a(i, j) = o * i + j + 1 = 3 * 1 + 0 + 1 = 4
で、2行目1列目は4になっています。
A j=1のとき、
a(i, j) = o * i + j + 1 = 3 * 1 + 1 + 1 = 5
で、2行目2列目は2になっています。
B j=2のとき、
a(i, j) = o * i + j + 1 = 3 * 1 + 2 + 1 = 6
で、2行目3列目は3になっています。
V i=2の場合
@ j=0のとき、
a(i, j) = o * i + j + 1 = 3 * 2 + 0 + 1 = 7
で、3行目1列目は1になっています。
A j=1のとき、
a(i, j) = o * i + j + 1 = 3 * 2 + 1 + 1 = 8
で、3行目2列目は2になっています。
B j=2のとき、
a(i, j) = o * i + j + 1 = 3 * 2 + 2 + 1 = 9
で、3行目3列目は3になっています。
W i=3の場合
@ j=0のとき、
a(i, j) = o * i + j + 1 = 3 * 3 + 0 + 1 = 10
で、4行目1列目は1になっています。
A j=1のとき、
a(i, j) = o * i + j + 1 = 3 * 3 + 1 + 1 = 11
で、4行目2列目は2になっています。
B j=2のとき、
a(i, j) = o * i + j + 1 = 3 * 3 + 2 + 1 = 12
で、4行目3列目は3になっています。
注目していただきたい点は、A7,A8,A9,A10の差です。
すべて3です。何故3かといいますと、列数が3だからです。
したがって、行が変わる度(つまり、iが変わる度)に3増えなければならないわけです。
a(i, j) = o * i + j + 1は、列数oが今の例では3ですから、行が変わる度に3増えるという要求を満たします。
次に、
'自然配列の表示
Sub f1(h As Byte, o As Byte)
Dim i As Byte, j As Byte
Cells(6, 1) = "自然配列"
For i = 0 To h - 1
For j = 0 To o - 1
Cells(7 + i, 1 + j) = a(i, j)
Next
Next
End Sub
を見てみましょう。
i=0,j=0のとき、Cells(7 + i, 1 + j) =Cells(7, 1) でこれは、A7です。
したがって、一番最初の数字1がA7に入ります。
以後のトレースはご自分でなさってください。
さて、一番頭が混乱するのは、
'自然配列の転置の表示
Sub f2(h As Byte, o As Byte)
Dim i As Byte, j As Byte
Cells(6, 3 + o) = "自然配列の転置"
For i = 0 To o - 1
For j = 0 To h - 1
Cells(7 + i, 3 + j + o) = a(j, i)
Next
Next
End Sub
ですね。
注目は、自然配列の表示のときの
Cells(6, 1) = "自然配列"
For i = 0 To h - 1
For j = 0 To o - 1
Cells(7 + i, 1 + j) = a(i, j)
Next
Next
と
Cells(6, 3 + o) = "自然配列の転置"
For i = 0 To o - 1
For j = 0 To h - 1
Cells(7 + i, 3 + j + o) = a(j, i)
Next
Next
の違いです。異なっている場所に色がついているのでお分かりですね。
まず、Cells(6, 1) とCells(6, 3 + o) の違いは、
2列間を開けるためです。それで、1と3ですが、 + oはなんでしょうか。
自然配列の3列に対応します。
『自然配列』が表示してある場所から、まず + oで3列ずらし、
そして、1と3によってさらに2列ずらすことに、『自然配列の転置』を適切な位置に表示しているのです。
さて、問題は
For i = 0 To h - 1
For j = 0 To o - 1
Cells(7 + i, 1 + j) = a(i, j)
Next
Next
と
For i = 0 To o - 1
For j = 0 To h - 1
Cells(7 + i, 3 + j + o) = a(j, i)
Next
Next
の違いです。
For i = 0 To o - 1
For j = 0 To h - 1
Cells(7 + i, 3 + j + o) = a(j,i)
Next
Next
の濃紺の部分だけが転置(縦と横を反対にする)され、Cells(7 + i, 3 + j + o)
は『自然配列の転置』の表示のときと同じで
+ oで3列ずらし、そして、1と3によってさらに2列ずらしていますが、
iとjは反対になっていません。
濃紺だけが転置さて、Cells(7 + i, 3 + j + o)は転置されていない点が味噌です。
Cells(7 + j, 3 + i + o)と両方を転置してしまうと、
結果が同じになってしまいます。
ですから、Cells(7 + i, 3 + j + o)でなければならないのです。
両辺の内の一方が転置され、他方は転置されていなければよいので、
Cells(6, 3 + o) = "自然配列の転置"
For i = 0 To h - 1
For j = 0 To o - 1
Cells(7 + j, 3 + i + o) = a(i, j)
Next
Next
でも正しい結果が得られます。濃紺の部分のみ転置されています。
最後に、
'逆自然配列の表示
Sub f3(h As Byte, o As Byte)
Dim i As Byte, j As Byte
Cells(6, 5 + h + o) = "逆自然配列"
For i = 0 To h - 1
For j = 0 To o - 1
Cells(7 + i, 5 + j + h + o) = (o - 1) * h + h + 1 - a(i, j)
Next
Next
End Sub
の部分を解説して解説は終了とします。違いは、紺だけです。
最初に3列をずらし、次に4列ずらしています。この4列の4は最初に入力してある行数の4です。
2番目の行列は、転置してあったので行が列に変わり4列になるのです。
最後に、課題を出してこの話を閉じます。
行数と列数が同じ行列を、正方行列といいます。
対象を正方行列のみとしますので、シートは少し変更して、
とします。次数は、行数=列数です。
今回は、実行を押すと、
となるようにしてください。逆転置とは、私の作った言葉で
赤い線に対して線対称になるものを指しています。
普通の転置は、紺の線に対して対称であるのにたいて、
逆の対角線に対して対称なので、逆転置と名付けたわけです。
後の意味は、実行画面を見ればお分かりになると思います。
vc++講義へ
vb講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座へ
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座へ
数学研究室に戻る