第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列間を開けるためです。それで、13ですが、 + oはなんでしょうか。
自然配列の3列に対応します。
『自然配列』が表示してある場所から、まず + oで3列ずらし、
そして、13によってさらに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列ずらし、そして、13によってさらに2列ずらしていますが、
iとjは反対になっていません。
濃紺
だけが転置さて、Cells(7 + i, 3 + j + o)は転置されていない点が味噌です。
Cells(7 + j, 3 + + 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列になるのです。

最後に、課題を出してこの話を閉じます。
行数と列数が同じ行列を、正方行列といいます。
対象を正方行列のみとしますので、シートは少し変更して、
シートとします。次数は、行数=列数です。
今回は、実行を押すと、
実行画面
となるようにしてください。逆転置とは、私の作った言葉で
逆転置赤い線に対して線対称になるものを指しています。
普通の転置は、転置紺の線に対して対称であるのにたいて、
逆の対角線に対して対称なので、逆転置と名付けたわけです。
後の意味は、実行画面を見ればお分かりになると思います。

第4話へ 第6話へ

004


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

数学研究室に戻る